在C#中传递值

ViV*_*ViV 9 c# pass-by-value

如何通过Parameter-by-Value将"MyClass"(C#)的对象传递给方法?例:

MyClass obj = new MyClass();
MyClass.DontModify(obj); //Only use it!
Console.Writeline(obj.SomeIntProperty);
Run Code Online (Sandbox Code Playgroud)

...

public static void DontModify(MyClass a)
{
    a.SomeIntProperty+= 100;// Do something more meaningful here
    return;
}
Run Code Online (Sandbox Code Playgroud)

Dan*_*lba 10

默认情况下,对象类型在C#中按值传递.但是,当您将对象引用传递给方法时,对象中的修改将保持不变.如果您希望对象不可变,则需要克隆它.

要做到这一点,请在您的类中实现ICloneable接口.这是一个如何使用ICloneable的模拟示例:

public class MyClass : ICloneable
{
  private int myValue;

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

  public void object Clone()
  {
     return new MyClass(myValue);
  }
}
Run Code Online (Sandbox Code Playgroud)

  • @ OlivierJacot-Descombes:[来自msdn](http://msdn.microsoft.com/de-de/library/system.object.memberwiseclone.aspx):_ MemberwiseClone方法通过创建一个新对象来创建浅拷贝,然后将当前对象的非静态字段复制到新对象.如果字段是值类型,则执行字段的逐位复制.**如果字段是引用类型,则复制引用但引用的对象不是; 因此,原始对象及其克隆引用相同的对象**.(编辑:我的第二个评论是在我开始之后...) (3认同)
  • 不幸的是,IClonable没有定义它是深层还是浅层副本.您最终可能会(在使用您自己没有编写的类时)仍在复制引用.因为它早于Generics,ICloneable返回一个对象,所以你需要施放...整个事情都相当难看. (2认同)
  • 你可以在`Clone`方法中简单地写`return MemberwiseClone();`. (2认同)
  • @linac:您可以编写类型化的 `Clone` 方法而不实现 `IClonable`。您甚至可以将其命名为“ShallowClone”或“DeepClone”以使事情更清楚。但我同意这并不能消除深度克隆的问题。 (2认同)

Ree*_*sey 8

默认情况下,它是按值传递的。但是,您是按值传递对象引用,这意味着您仍然可以编辑对象内的值。

为了防止对象根本无法更改,您需要在将其传递到您的方法之前实际克隆该对象。这将要求您实现一些创建新实例的方法,该实例是原始对象的副本,然后传入该副本。


Mus*_*sis 5

public static void DontModify(MyClass a)
{
    MyClass clone = (MyClass)a.Clone();
    clone.SomeIntProperty+= 100;// Do something more meaningful here
    return;
}
Run Code Online (Sandbox Code Playgroud)