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

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

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

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

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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
24
0
13 818
4

Ответы 4

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

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

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

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

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

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

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

По этой ссылке (уже размещенной): 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#

Другие вопросы по теме