在C#中按值传递引用类型

时间:2020-12-14 16:09:49

I want to pass a reference type by value to a method in C#. Is there a way to do it.

我想按值将引用类型传递给C#中的方法。有没有办法做到这一点。

In C++, I could always rely on the copy constructor to come into play if I wanted to pass by Value. Is there any way in C# except: 1. Explicitly creating a new object 2. Implementing IClonable and then calling Clone method.

在C ++中,如果我想通过Value传递,我总是可以依赖复制构造函数来发挥作用。在C#中有什么办法除外:1。显式创建一个新对象2.实现IClonable然后调用Clone方法。

Here's a small example:

这是一个小例子:

Let's take a class A in C++ which implements a copy constructor.

让我们用C ++中的A类来实现一个拷贝构造函数。

A method func1(Class a), I can call it by saying func1(objA) (Automatically creates a copy)

一个方法func1(Class a),我可以通过说func1(objA)来调用它(自动创建一个副本)

Does anything similar exist in C#. By the way, I'm using Visual Studio 2005.

C#中是否存在类似的东西。顺便说一句,我正在使用Visual Studio 2005。

5 个解决方案

#1


20  

No, there is no copy-constructor equivalent in C#. What you are passing (by value) is a reference.

不,C#中没有等效的拷贝构造函数。你传递的是什么(按价值)是一个参考。

ICloneable is also risky, since it is poorly defined whether that is deep vs shallow (plus it isn't very well supported). Another option is to use serialization, but again, that can quickly draw in much more data than you intended.

ICloneable也有风险,因为它的定义很差,无论是深层还是浅层(加上它得不到很好的支持)。另一个选择是使用序列化,但同样,它可以快速绘制比您预期更多的数据。

If the concern is that you don't want the method making changes, you could consider making the class immutable. Then nobody can do anything nasty to it.

如果担心您不希望方法进行更改,则可以考虑使该类不可变。然后没有人可以做任何令人讨厌的事情。

#2


8  

As already explained, there's no equivalent to C++'s copy constructors.

正如已经解释过的那样,没有与C ++的拷贝构造函数等价的东西。

Another technique is to use a design where the objects are immutable. For immutable objects there is no (semantic) difference between passing a reference and a copy. This is the way System.String is designed. Other systems (notably functional languages) apply this technique much more.

另一种技术是使用对象不可变的设计。对于不可变对象,传递引用和副本之间没有(语义)差异。这是System.String的设计方式。其他系统(特别是函数式语言)更多地应用了这种技术。

#3


1  

This link shd answer ur question - http://msdn.microsoft.com/en-us/library/s6938f28(VS.80).aspx

这个链接shd回答你的问题 - http://msdn.microsoft.com/en-us/library/s6938f28(VS.80).aspx

#4


1  

According to this link (already posted): http://msdn.microsoft.com/en-us/library/s6938f28(VS.80).aspx

根据此链接(已发布):http://msdn.microsoft.com/en-us/library/s6938f28(VS.80).aspx

Passing a reference type by value is shown below. The reference type arr is passed by value to the Change method.

按值传递引用类型如下所示。引用类型arr通过值传递给Change方法。

Any changes will affect the original item unless the array is assigned a new memory location in which case, the change is entirely local to the method.

除非为阵列分配了新的内存位置,否则任何更改都将影响原始项目,在这种情况下,更改完全是本地方法的。

class PassingRefByVal 
{
    static void Change(int[] pArray)
    {
        pArray[0] = 888;  // This change affects the original element.
        pArray = new int[5] {-3, -1, -2, -3, -4};   // This change is local.
        System.Console.WriteLine("Inside the method, the first element is: {0}", pArray[0]);
    }

    static void Main() 
    {
        int[] arr = {1, 4, 5};
        System.Console.WriteLine("Inside Main, before calling the method, the first element is: {0}", arr [0]);

        Change(arr);
        System.Console.WriteLine("Inside Main, after calling the method, the first element is: {0}", arr [0]);
    }
}

In closing, for a more in depth discussion, see the post by Jon Skeet in this question:

最后,有关更深入的讨论,请参阅Jon Skeet在此问题中的帖子:

Passing Objects By Reference or Value in C#

在C#中通过引用或值传递对象

#5


0  

take a look at this

看看这个

public class Product
{
   public string Name;
   public string Color;
   public string Category;

   public Product(Product o)
   {
      this.Name=o.Name;
      this.Color=o.Color;
      this.Category=o.Category;
   } 
   // Note we need to give a default constructor when override it

   public Product()
   {
   }
} 
public Product Produce(Product sample)
{
   Product p=new Product(sample);
   p.Category="Finished Product";
   return p;
}
Product sample=new Product();
sample.Name="Toy";
sample.Color="Red";
sample.Category="Sample Product";
Product p=Produce(sample);
Console.WriteLine(String.Format("Product: Name={0}, Color={1}, Category={2}", p.Name, p.Color, p.Category));
Console.WriteLine(String.Format("Sample: Name={0}, Color={1}, Category={2}", sample.Name, sample.Color, sample.Category));

#1


20  

No, there is no copy-constructor equivalent in C#. What you are passing (by value) is a reference.

不,C#中没有等效的拷贝构造函数。你传递的是什么(按价值)是一个参考。

ICloneable is also risky, since it is poorly defined whether that is deep vs shallow (plus it isn't very well supported). Another option is to use serialization, but again, that can quickly draw in much more data than you intended.

ICloneable也有风险,因为它的定义很差,无论是深层还是浅层(加上它得不到很好的支持)。另一个选择是使用序列化,但同样,它可以快速绘制比您预期更多的数据。

If the concern is that you don't want the method making changes, you could consider making the class immutable. Then nobody can do anything nasty to it.

如果担心您不希望方法进行更改,则可以考虑使该类不可变。然后没有人可以做任何令人讨厌的事情。

#2


8  

As already explained, there's no equivalent to C++'s copy constructors.

正如已经解释过的那样,没有与C ++的拷贝构造函数等价的东西。

Another technique is to use a design where the objects are immutable. For immutable objects there is no (semantic) difference between passing a reference and a copy. This is the way System.String is designed. Other systems (notably functional languages) apply this technique much more.

另一种技术是使用对象不可变的设计。对于不可变对象,传递引用和副本之间没有(语义)差异。这是System.String的设计方式。其他系统(特别是函数式语言)更多地应用了这种技术。

#3


1  

This link shd answer ur question - http://msdn.microsoft.com/en-us/library/s6938f28(VS.80).aspx

这个链接shd回答你的问题 - http://msdn.microsoft.com/en-us/library/s6938f28(VS.80).aspx

#4


1  

According to this link (already posted): http://msdn.microsoft.com/en-us/library/s6938f28(VS.80).aspx

根据此链接(已发布):http://msdn.microsoft.com/en-us/library/s6938f28(VS.80).aspx

Passing a reference type by value is shown below. The reference type arr is passed by value to the Change method.

按值传递引用类型如下所示。引用类型arr通过值传递给Change方法。

Any changes will affect the original item unless the array is assigned a new memory location in which case, the change is entirely local to the method.

除非为阵列分配了新的内存位置,否则任何更改都将影响原始项目,在这种情况下,更改完全是本地方法的。

class PassingRefByVal 
{
    static void Change(int[] pArray)
    {
        pArray[0] = 888;  // This change affects the original element.
        pArray = new int[5] {-3, -1, -2, -3, -4};   // This change is local.
        System.Console.WriteLine("Inside the method, the first element is: {0}", pArray[0]);
    }

    static void Main() 
    {
        int[] arr = {1, 4, 5};
        System.Console.WriteLine("Inside Main, before calling the method, the first element is: {0}", arr [0]);

        Change(arr);
        System.Console.WriteLine("Inside Main, after calling the method, the first element is: {0}", arr [0]);
    }
}

In closing, for a more in depth discussion, see the post by Jon Skeet in this question:

最后,有关更深入的讨论,请参阅Jon Skeet在此问题中的帖子:

Passing Objects By Reference or Value in C#

在C#中通过引用或值传递对象

#5


0  

take a look at this

看看这个

public class Product
{
   public string Name;
   public string Color;
   public string Category;

   public Product(Product o)
   {
      this.Name=o.Name;
      this.Color=o.Color;
      this.Category=o.Category;
   } 
   // Note we need to give a default constructor when override it

   public Product()
   {
   }
} 
public Product Produce(Product sample)
{
   Product p=new Product(sample);
   p.Category="Finished Product";
   return p;
}
Product sample=new Product();
sample.Name="Toy";
sample.Color="Red";
sample.Category="Sample Product";
Product p=Produce(sample);
Console.WriteLine(String.Format("Product: Name={0}, Color={1}, Category={2}", p.Name, p.Color, p.Category));
Console.WriteLine(String.Format("Sample: Name={0}, Color={1}, Category={2}", sample.Name, sample.Color, sample.Category));