C # Alcance de variables frente a objetos cuando está parametrizado en métodos

StackOverflow https://stackoverflow.com/questions/624217

  •  05-07-2019
  •  | 
  •  

Pregunta

Hago un uso extensivo de la herencia, el polimorfismo y la encapsulación, pero me di cuenta de que no conocía el siguiente comportamiento sobre el alcance de un objeto frente a una variable. La diferencia se muestra mejor con el 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"; }
}

Entonces pensé que cuando una variable se pasa a un método, los cambios se limitan al alcance del método. Pero parece que si un objeto se pasa a un método que cambia a sus propiedades se extiende más allá del método.

Podría aceptar esto si la regla es que este comportamiento existe para el objeto y no para las variables, pero en .net todo es un objeto, una cadena (como la del ejemplo es System.String) Entonces, ¿cuál es la regla, cómo puede Predigo el alcance de un parámetro que paso en un método?

¿Fue útil?

Solución

Nunca pasa un objeto como argumento, solo pasa una referencia o un valor de tipo de valor. A menos que use la palabra clave ref , los argumentos se pasan por valor, es decir, el valor inicial del parámetro es el valor evaluado del argumento, y los cambios en el valor del parámetro no son vistos por el llamante .

Sin embargo, es muy importante entender que el valor del parámetro (para un tipo de referencia) es solo la referencia . Si cambia el contenido del objeto al que hace referencia la referencia, la persona que llama verá que cambiar .

Es un tema que merece más que unos pocos párrafos. Le sugiero que lea mi artículo sobre el parámetro pasar en .NET para más información.

Otros consejos

Creo que acabo de descubrirlo buscando en Google, algunas cosas en .net son " valor " tipos y otros son " referencia " tipos, por lo que para los tipos de valor, el valor se duplica al calcularse en un método, pero los tipos de referencia tienen un puntero similar, o la referencia se pasa al método que obviamente comparte el mismo alcance que el padre. Entonces, mi pregunta es cómo saber si algo es un tipo de valor o no, veo que las estructuras como ints son todos tipos de valores, pero las cadenas parecen comportarse como estructuras aunque sean objetos System.String?

Una clase (Obj en su caso) es una tipo de referencia , así que cuando llamas a la función, lo que realmente estás haciendo es pasar una referencia (básicamente, puedes pensar en esto como un puntero de tipo seguro) a este objeto. Si desea evitar cambios en objetos mutables (es decir, tipos de clase / referencia), entonces necesita clonar este objeto antes de pasarlo a la función apropiada (o simplemente considerar convertirlo en una estructura para que se copie por valor).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top