Como: saber a diferença entre passar uma estrutura e passar uma referência de classe para um método (guia de programação do C#)
O exemplo a seguir demonstra como passando um struct para um método difere passando um classe instância para um método.No exemplo, ambos os argumentos (instância de classe e destruct ) são passados por valor e os dois métodos de alterar o valor de um campo do argumento.No entanto, os resultados dos dois métodos não são iguais porque o que é passado quando você passa uma struct difere o que é passado quando você passa uma instância de uma classe.
Porque uma struct é um tipo de valor, quando você passar uma struct pelo valor de para um método, o método recebe e opera em uma cópia doargumento struct. O método não tem acesso ao original struct no método de chamada e, portanto, não é possível alterá-lo de forma alguma.O método pode alterar apenas a cópia.
Uma instância da classe é um tipo de referência, não é um tipo de valor.Quando um tipo de referência é passado por valor de para um método, o método recebe uma cópia da referência à instância da classe .Ou seja, o método recebe uma cópia do endereço da instância, não uma cópia da própria instância.A instância da classe no método de chamada possui um endereço, o parâmetro no método chamado possui uma cópia do endereço e os dois endereços se referir ao mesmo objeto.Como o parâmetro contém apenas uma cópia do endereço, o método chamado não é possível alterar o endereço da instância da classe no métodode chamada.No entanto, o chamado método pode usar o endereço para acessar os membros de classe que referenciam o endereço original e a cópia.Se o método chamado for alterado para um membro da classe , também altera a instância da classe original no método de chamada.
A saída de exemplo a seguir ilustra a diferença.O valor da willIChangeo campo da instância da classe é alterado pela chamada ao método ClassTaker como o método usa o endereço no parâmetro para localizar o campo especificado da instância da classe . O willIChange campo do struct no método de chamada não é alterado pela chamada ao método StructTaker como o valor do argumento é uma cópia do struct propriamente dito, não uma cópia do seu endereço. StructTakeras alterações na cópia e a cópia é perdido quando a chamada para StructTaker for concluída.
Exemplo
class TheClass
{
public string willIChange;
}
struct TheStruct
{
public string willIChange;
}
class TestClassAndStruct
{
static void ClassTaker(TheClass c)
{
c.willIChange = "Changed";
}
static void StructTaker(TheStruct s)
{
s.willIChange = "Changed";
}
static void Main()
{
TheClass testClass = new TheClass();
TheStruct testStruct = new TheStruct();
testClass.willIChange = "Not Changed";
testStruct.willIChange = "Not Changed";
ClassTaker(testClass);
StructTaker(testStruct);
Console.WriteLine("Class field = {0}", testClass.willIChange);
Console.WriteLine("Struct field = {0}", testStruct.willIChange);
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
Class field = Changed
Struct field = Not Changed
*/
Consulte também
Referência
Classes (guia de programação do C#)
Structs (guia de programação do C#)
Passando parâmetros (guia de programação do C#)