Подтвердить что ты не робот

Объект передан как параметр другому классу, по значению или ссылке?

В С# я знаю, что по умолчанию любые параметры, переданные в функцию, будут копироваться, то есть внутри функции есть локальная копия параметра. Но как насчет того, когда объект передается как параметр в другой класс?

Будет ли передан следующий сценарий по ссылке или по значению:

class MyClass {
   private Object localObj;

   public void SetObject(Object obj) {
      localObj = obj;
   }
}

void Main() {
   Object someTestObj = new Object();
   someTestObj.name = "My Name";
   MyClass cls = New MyClass();
   cls.SetObject(someTesetObj);
}

В этом случае будет ли переменная класса localObj иметь ту же копию, что и someTestObj, созданная в классе драйвера Main? Или две переменные указывали бы на другой экземпляр объекта?

4b9b3361

Ответ 1

Объекты будут передаваться по ссылке независимо от методов одного класса или другого класса. Ниже приведена модифицированная версия того же кода примера, который поможет вам понять. Значение будет изменено на "xyz."

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    public class Employee
    {
        public string Name { get; set; }
    }

    public class MyClass
    {
        public Employee EmpObj;

        public void SetObject(Employee obj)
        {
            EmpObj = obj;
        }
    }

    public class Program
    {
       static void Main(string[] args)
        {
            Employee someTestObj = new Employee();
            someTestObj.Name = "ABC";

            MyClass cls = new MyClass();
            cls.SetObject(someTestObj);

            Console.WriteLine("Changing Emp Name To xyz");
            someTestObj.Name = "xyz";

            Console.WriteLine("Accessing Assigned Emp Name");
            Console.WriteLine(cls.EmpObj.Name); 

           Console.ReadLine();
       }       
    }
 }

Ответ 2

"Объекты" НИКОГДА не передаются в С# - "объекты" не являются значениями на языке. Единственными типами языка являются примитивные типы, типы структур и т.д. И ссылочные типы. Нет "типов объектов".

Типы Object, MyClass и т.д. являются ссылочными типами. Их значения - "ссылки" - указатели на объекты. Объекты могут обрабатываться только через ссылки - когда вы делаете new на них, вы получаете ссылку, оператор . работает по ссылке; и т.д. Нет способа получить переменную, значение которой "является" объектом, потому что нет типов объектов.

Все типы, включая ссылочные типы, могут передаваться по значению или по ссылке. Параметр передается по ссылке, если у него есть ключевое слово, например ref или out. Параметр SetObject метод obj (который имеет ссылочный тип) не имеет такого ключевого слова, поэтому он передается значением - эта ссылка передается по значению.

Ответ 3

Предполагая, что someTestObj является class, а не a struct, объект передается по ссылке, что означает, что оба obj и someTestObj относятся к одному и тому же объекту. Например. изменение name в одном изменит его в другом. Однако, в отличие от того, если вы передали его с помощью ключевого слова ref, установка obj = somethingElse не изменится someTestObj.

Ответ 4

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

Другими словами, мой метод Increment изменяет свой параметр myClass при каждом вызове.

class Program
{
    static void Main(string[] args)
    {
        MyClass myClass = new MyClass();
        Console.WriteLine(myClass.Value);  // Displays 1
        Increment(myClass);
        Console.WriteLine(myClass.Value);  // Displays 2
        Increment(myClass);
        Console.WriteLine(myClass.Value);  // Displays 3           
        Increment(myClass);
        Console.WriteLine(myClass.Value);  // Displays 4
        Console.WriteLine("Hit Enter to exit.");
        Console.ReadLine();
    }

    public static void Increment(MyClass myClassRef)
    {
        myClassRef.Value++;
    }
}

public class MyClass
{
    public int Value {get;set;}
    public MyClass()
    {
        Value = 1;
    }
}

Ответ 5

Объект, если он передан как тип значения, тогда изменения, внесенные в элементы объекта внутри метода, также оказываются вне метода.              Но если сам объект установлен на другой объект или повторно инициализирован, он не будет отображаться вне метода. Поэтому я бы сказал, что объект в целом передается только как Valuetype, но члены объекта по-прежнему являются ссылочным типом.

        private void button1_Click(object sender, EventArgs e)
    {
        Class1 objc ;
         objc = new Class1();
        objc.empName = "name1";
        checkobj( objc);
        MessageBox.Show(objc.empName);  //propert value changed; but object itself did not change
    }
    private void checkobj ( Class1 objc)
    {
        objc.empName = "name 2";
        Class1 objD = new Class1();
        objD.empName ="name 3";
        objc = objD ;
        MessageBox.Show(objc.empName);  //name 3
    }

Ответ 6

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

Вот статья, на которую можно ссылаться: Глубокие объекты клонирования

Ответ 7

В общем случае "объект" - это экземпляр класса, который представляет собой "изображение"/"fingerprint" класса, созданного в памяти (через ключевое слово New).
Переменная типа объекта относится к этой ячейке памяти, то есть по существу содержит адрес в памяти.
Таким образом, параметр типа объекта передает ссылку/"ссылку" на объект, а не копию всего объекта.