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

Обновлен: Ноябрь 2007

Определение класса или структуры подобно чертежу, на котором указаны действия, выполняемые типом. В сущности, объект является блоком памяти, выделенной и настроенной в соответствии с чертежом. Программа может создать множество объектов одного класса. Объекты также называют экземплярами. Они могут храниться либо в именованной переменной, либо в массиве или коллекции. Клиентский код — это код, использующий эти переменные для вызова методов и доступа к открытым свойствам объекта. В объектно-ориентированном языке, таком как C#, стандартная программа состоит из нескольких динамически взаимодействующих объектов.

ms173110.alert_note(ru-ru,VS.90).gifПримечание.

Поведение статических типов отличается от описанного здесь поведения. Дополнительные сведения см. в разделе Статические классы и члены статических классов (руководство по программированию в C#).

Экземпляры структуры и экземпляры класса

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

Экземпляры классов создаются с помощью оператора new. В следующем примере Person является типом, а person1 и person 2 — являются экземплярами или объектами этого типа.

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
    //Other properties, methods, events...
}

class Program
{
    static void Main()
    {
        Person person1 = new Person("Leopold", 6);
        Console.WriteLine("person1 Name = {0} Age = {1}", person1.Name, person1.Age);

        // Declare a new person, assign person1 to it.
        Person person2 = person1;

        //Change the name of person2, and person1 also changes.
        person2.Name = "Molly";
        person2.Age = 16;

        Console.WriteLine("person2 Name = {0} Age = {1}", person2.Name, person2.Age);
        Console.WriteLine("person1 Name = {0} Age = {1}", person2.Name, person2.Age);

        // Keep the console open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();        

    }
}
/*
    Output:
    person1 Name = Leopold Age = 6
    person2 Name = Molly Age = 16
    person1 Name = Molly Age = 16
*/

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

public struct Person
{
    public string Name;
    public int Age;
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

public class Application
{
    static void Main()
    {
        // Create a struct instance and initialize by using "new".
        // Memory is allocated on thread stack.
        Person p1 = new Person("Alex", 9);
        Console.WriteLine("p1 Name = {0} Age = {1}", p1.Name, p1.Age);

        // Create a new struct object. Note that a struct can be initialized
        // without using "new".
        Person p2 = p1;

        // Assign values to p2 members.
        p2.Name = "Spencer";
        p2.Age = 7;
        Console.WriteLine("p2 Name = {0} Age = {1}", p2.Name, p2.Age);

        // p1 values remain unchanged because p2 is a copy.
        Console.WriteLine("p1 Name = {0} Age = {1}", p1.Name, p1.Age);

        // Keep the console open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey(); 
    }
}
/*
  Output:
    p1 Name = Alex Age = 9
    p2 Name = Spencer Age = 7
    p1 Name = Alex Age = 9
*/

Память для p1 и p2 выделена в стеке потока. Эта память освобождена наряду с типом или методом, в котором она объявляется. Эта одна причина того, почему структуры копируются при присваивании. Напротив, при выходе всех ссылок на объект из области действия среда CLR выполняет автоматическое освобождение памяти (сборку мусора), выделенной для экземпляра класса. Возможность детерминированного уничтожения объекта класса, имеющаяся в C++, в данном случае отсутствует. Дополнительные сведения о сборке мусора в .NET Framework см. в разделе Сборка мусора.

ms173110.alert_note(ru-ru,VS.90).gifПримечание.

В среде CLR процесс выделения и освобождения памяти в управляемой куче значительно оптимизирован. В большинстве случаев нет существенной разницы в затратах производительности на выделение экземпляра класса в куче и выделение экземпляра структуры в стеке.

Идентификация объекта и идентификация значения

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

  • Чтобы определить, ссылаются ли два экземпляра класса на одно расположение в памяти (это значит, что они имеют одинаковый идентификатор), воспользуйтесь статическим методом Equals. (System.Object является неявным базовым классом для всех типов значений и ссылочных типов, включая структуры и классы, определенные пользователем).

  • Чтобы определить, имеют ли поля экземпляра в двух экземплярах структур одинаковые значения, воспользуйтесь методом ValueType.Equals. Поскольку все структуры неявно наследуют от System.ValueType, метод может быть вызван непосредственно в объекте, как показано в следующем примере.

Person p1 = new Person("Wallace", 75);
Person p2;
p2.Name = "Wallace";
p2.Age = 75;

if (p2.Equals(p1))
    Console.WriteLine("p2 and p1 have the same values.");

// Output: p2 and p1 have the same values.

Реализация System.ValueTypeEquals использует отображение, поскольку необходимо определить поля, находящиеся в любой структуре. При создании собственных структур переопределите метод Equals для предоставления эффективного алгоритма равенства, соответствующего вашему типу.

Связанные разделы

Дополнительные сведения:

См. также

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

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

Типы значений в системе общих типов CTS

Классы в системе общих типов CTS

Ссылки

object (справочник по C#)

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

класс (Справочник по C#)

struct (справочник по C#)

Оператор new (Справочник по C#)