Pergunta

I fazem uso extensivo de herança, polymorphisim, e encapsulamento, mas eu só percebi que eu não sabia o seguinte comportamento sobre o escopo de um objeto contra uma variável. A diferença é melhor mostrado com código:

public class Obj
{
    public string sss {get; set;}

    public Obj()
    {
        sss = "0";
    } 
}     

public partial class testScope : System.Web.UI.Page
 {
    protected void Page_Load(object sender, EventArgs e)
    { 
        Obj a = new Obj(); 
        String sss = "0";            
        Context.Response.Write(sss); // 0

        FlipString(sss);
        FlipString(a.sss);
        Context.Response.Write(sss + a.sss); // 0 0

        FlipObject(a);
        Context.Response.Write(a.sss); // 1
        Context.Response.End();
    }

    public void FlipString(string str)
    { str = "1"; }

    public void FlipObject(Obj str)
    { str.sss = "1"; }
}

Então eu pensei que quando uma variável é passada para um método que alterações são limitadas ao escopo do método. Mas parece que, se um objeto é passado para um método que muda para suas propriedades se estender além do método.

Eu poderia aceitar isso, se a regra era que este comportamento existe para variáveis ??de objeto e não mas em tudo .net é um objeto, um string (como o que no exemplo é System.String) Então, qual a regra, como pode i prever o alcance de um parâmetro que eu passar em um método?

Foi útil?

Solução

Você nunca passar um objeto como um argumento - você só passar um referência ou um valor de tipo de valor. A menos que você use a palavra-chave ref, os argumentos são passados ??por valor -. Ou seja, o valor inicial do parâmetro é o valor avaliado do argumento, e mudanças no valor do parâmetro não são vistas pelo chamador

No entanto, é muito importante entender que o valor do parâmetro (para um tipo de referência) é apenas a referência . Se você alterar o conteúdo do objeto que a referência se refere, em seguida, que mudança irá ser visto pelo chamador.

É um tema que merece mais do que alguns parágrafos - Eu sugiro que você leia o meu artigo sobre parâmetro passando em .NET para obter mais informações.

Outras dicas

Eu acho que eu só percebi isso googleing ao redor, algumas coisas em .net são "valor" tipos e outros são tipos de "referência", por isso para tipos de valor o valor é duplicado quando está sendo empacotado em um método, mas os tipos de referência tem um como um ponteiro, ou de referência passado para o método que obviamente partilha o mesmo alcance como o pai. Assim, pois, a minha pergunta é como pode dizer se algo é um tipo de valor ou não, vejo que estruturas como ints são todos os tipos de valor, mas Cordas parecem comportar-se como estruturas, mesmo que eles são objetos System.String?

classe A (Obj no seu caso) é um tipo de referência , então quando você chamar a função que você está fazendo realmente está passando uma referência (basicamente você pode pensar nisso como um ponteiro de tipo seguro) para este objeto. Se você quer evitar alterações em objetos mutáveis ??(ou seja, tipos de classe / referência), então você precisa para clonar este objeto antes de passá-lo para a função apropriada (ou simplesmente tornando-se considerar uma estrutura para que ele seja copiado por valor).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top