2012-06-21 17 views
6

¿Cómo puedo pasar un objeto de una "MyClass" (C#) por parámetro por valor a un método? ejemplo:Pasar por valor en C#

MyClass obj = new MyClass(); 
MyClass.DontModify(obj); //Only use it! 
Console.Writeline(obj.SomeIntProperty); 

...

public static void DontModify(MyClass a) 
{ 
    a.SomeIntProperty+= 100;// Do something more meaningful here 
    return; 
} 
+4

La gente puede decirle que use un 'struct'. No lo hagas – SLaks

+0

descarga: (CloneExtensions) de nuget. Extenderá el objeto C# con el método GetClone() que acepta indicadores donde puede usar para indicar que desea una copia poco profunda. https://www.nuget.org/packages/CloneExtensions/1.2.0 – alsafoo

Respuesta

9

Por defecto, los tipos de objeto se pasan por valor en C#. Pero cuando pasa una referencia de objeto a un método, las modificaciones en el objeto se conservan. Si quiere que su objeto sea inmutable, necesita clon.

Para hacerlo, implemente la interfaz ICloneable en su clase. Aquí es un ejemplo simulacro de cómo utilizar ICloneable:

public class MyClass : ICloneable 
{ 
    private int myValue; 

    public MyClass(int val) 
    { 
    myValue = val; 
    } 

    public void object Clone() 
    { 
    return new MyClass(myValue); 
    } 
} 
+2

Desafortunadamente IClonable no define si es una copia profunda o superficial. Es posible que termine (al usar clases que no escribió usted mismo) copiando referencias en algún lugar de la línea. Y, como es anterior a Generics, ICloneable devuelve un objeto, por lo que debe lanzar ... todo es bastante feo. – linac

+2

Simplemente puede escribir 'return MemberwiseClone();' en el método 'Clone'. –

+0

Supongo que la clase que el usuario necesita clonar es una clase escrita en sellf al leer el código de muestra. En este caso, puede controlar el clon creando un nuevo objeto. Por supuesto, necesita clonar tipos incrustados si es necesario. –

4

Por defecto, se pasa por valor. Sin embargo, está pasando la referencia de objeto por valor, lo que significa que aún puede editar valores dentro del objeto.

Para evitar que el objeto pueda cambiar, deberá clonar el objeto antes de pasarlo a su método. Esto requeriría que implemente algún método para crear una instancia nueva que sea una copia de su objeto original, y luego pasar la copia.

2
public static void DontModify(MyClass a) 
{ 
    MyClass clone = (MyClass)a.Clone(); 
    clone.SomeIntProperty+= 100;// Do something more meaningful here 
    return; 
} 
1

Puede crear un método de clonación en su objeto para pasar el valor de retorno a su método. C# no puede pasar los tipos de referencia por valor, por lo que esta podría ser una buena alternativa.

public MyClass CreateClone() 
{ 
    return new MyClass() { SomeIntProperty = this.SomeIntProperty }; 
} 
1
class Program 
{ 
    static void Main(string[] args) 
    { 
     Person p1 = new Person() 
     { 
      Name = "Alsafoo", 
      Address = new Address() 
      { 
       City = "Chicago" 
      } 
     }; 

     Person p2 = new Person(p1.Address); 
     p2 = p1.GetClone(CloningFlags.Shallow); 
     p2.Name = "Ahmed"; 
     p2.Address = new Address(){City = "Las Vegas"}; 
     Console.WriteLine("p1 first name: {1} --- p1 city: {2} {0}p2 first name: {3} ---- p2 city: {4}", 
      Environment.NewLine, p1.Name, p1.Address.City, p2.Name, p2.Address.City); 
     Console.ReadKey(); 
    } 
} 
public class Person 
{ 
    public Person() 
    {} 
    public Person(Address a) 
    { 
     Address = a; 
    } 
    public string Name { get; set; } 
    public Address Address { get; set; }   
} 

public class Address 
{ 
    public string City { get; set; } 
} 

Descargar esta extensión https://www.nuget.org/packages/CloneExtensions/1.2.0

Cuestiones relacionadas