Передача ссылочных типов по значению в C # - PullRequest
21 голосов
/ 05 ноября 2008

Я хочу передать ссылочный тип по значению методу в C #. Есть ли способ сделать это.

В C ++ я всегда мог рассчитывать на конструктор копирования, если бы хотел пройти мимо Value. Есть ли способ в C #, кроме: 1. Явное создание нового объекта 2. Реализация IClonable, а затем вызов метода Clone.

Вот небольшой пример:

Давайте возьмем класс A в C ++, который реализует конструктор копирования.

Метод func1 (Class a), я могу вызвать его, говоря func1 (objA) (Автоматически создает копию)

Существует ли что-нибудь подобное в C #. Кстати, я использую Visual Studio 2005.

Ответы [ 5 ]

20 голосов
/ 05 ноября 2008

Нет, в C # нет эквивалента конструктора копирования. То, что вы передаете (по значению), является ссылкой .

ICloneable также рискованно, поскольку плохо определено, является ли это глубоким или мелким (плюс это не очень хорошо поддерживается). Другой вариант - использовать сериализацию, но опять же, это может быстро привлечь гораздо больше данных, чем вы предполагали.

Если проблема заключается в том, что вы не хотите, чтобы метод вносил изменения, вы можете сделать класс неизменным. Тогда никто не может сделать с ним ничего противного.

8 голосов
/ 05 ноября 2008

Как уже объяснено, нет эквивалента конструкторам копирования C ++.

Другая техника заключается в использовании дизайна, в котором объекты неизменны. Для неизменяемых объектов нет (семантической) разницы между передачей ссылки и копии. Так устроен System.String. Другие системы (особенно функциональные языки) применяют эту технику гораздо чаще.

1 голос
/ 30 ноября 2015

По этой ссылке (уже размещено): http://msdn.microsoft.com/en-us/library/s6938f28(VS.80).aspx

Передача ссылочного типа по значению показана ниже. Ссылочный тип arr по значению передается в метод Change.

Любые изменения будут влиять на исходный элемент, если массиву не назначено новое место в памяти, и в этом случае изменение полностью локально для метода.

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]);
    }
}

В заключение, для более глубокого обсуждения см. Пост Джона Скита в этом вопросе:

Передача объектов по ссылке или значению в C #

1 голос
/ 08 апреля 2010

Эта ссылка ответит на ваш вопрос - http://msdn.microsoft.com/en-us/library/s6938f28(VS.80).aspx

0 голосов
/ 21 мая 2011

взгляните на это

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));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...