Поделиться через


Практическое руководство. Определение различия между передачей структуры и ссылки класса в метод (Руководство по программированию в C#)

В следующем примере демонстрируется передача структура метода отличается от передачи экземпляр класс методу. В примере оба из аргументов (экземпляр структуры и класса) передаются по значению и обоими методами изменяют значение одного поля аргумента. Однако результаты " 2 метод не совпадают, потому что передается при передаче структура отличается от передается при передаче экземпляра класса.

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

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

Вывод следующем примере проиллюстрированы различия. Значение поля willIChange экземпляра класса изменен вызовом метода ClassTaker поскольку метод использует адрес в параметре, чтобы найти указанное поле экземпляра класса. Поле willIChange структуры в вызывающем методе не изменяется при вызове метода StructTaker поскольку значение аргумента копия структуры, а не саму копии своего адреса. StructTaker изменяет копии и копии будут потеряны, если вызов завершается StructTaker.

Пример

class TheClass
{
    public string willIChange;
}

struct TheStruct
{
    public string willIChange;
}

class TestClassAndStruct
{
    static void ClassTaker(TheClass c)
    {
        c.willIChange = "Changed";
    }

    static void StructTaker(TheStruct s)
    {
        s.willIChange = "Changed";
    }

    static void Main()
    {
        TheClass testClass = new TheClass();
        TheStruct testStruct = new TheStruct();

        testClass.willIChange = "Not Changed";
        testStruct.willIChange = "Not Changed";

        ClassTaker(testClass);
        StructTaker(testStruct);

        Console.WriteLine("Class field = {0}", testClass.willIChange);
        Console.WriteLine("Struct field = {0}", testStruct.willIChange);

        // Keep the console window open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/* Output:
    Class field = Changed
    Struct field = Not Changed
*/

См. также

Ссылки

Классы (Руководство по программированию на C#)

Структуры (Руководство по программированию на C#)

Передача параметров (Руководство по программированию в C#)

Основные понятия

Руководство по программированию на C#