Objetos não são passados. Por padrão, o argumento é avaliado e seu valor é passado, por valor, como o valor inicial do parâmetro do método que você está chamando. Agora, o ponto importante é que o valor é uma referência para tipos de referência - uma maneira de chegar a um objeto (ou nulo). As alterações nesse objeto serão visíveis no chamador. No entanto, alterar o valor do parâmetro para se referir a um objeto diferente não será visível quando você estiver usando a passagem por valor, que é o padrão para todos os tipos.
Se você deseja usar passagem por referência, deve usar out
ou ref
, se o tipo de parâmetro é um tipo de valor ou um tipo de referência. Nesse caso, efetivamente a variável em si é passada por referência; portanto, o parâmetro usa o mesmo local de armazenamento que o argumento - e as alterações no próprio parâmetro são vistas pelo chamador.
Assim:
public void Foo(Image image)
{
// This change won't be seen by the caller: it's changing the value
// of the parameter.
image = Image.FromStream(...);
}
public void Foo(ref Image image)
{
// This change *will* be seen by the caller: it's changing the value
// of the parameter, but we're using pass by reference
image = Image.FromStream(...);
}
public void Foo(Image image)
{
// This change *will* be seen by the caller: it's changing the data
// within the object that the parameter value refers to.
image.RotateFlip(...);
}
Eu tenho um artigo que entra em muito mais detalhes nisso . Basicamente, "passar por referência" não significa o que você pensa que significa.