#c#
#c#
Вопрос:
-
Почему метод Calcu1 имеет тот же код, что и метод Calcu2 в ILSpy, в то время как другие нет?
-
Хотя это разные типы (некоторые из них имеют ссылочный тип, другие — тип значения), почему метод Calcu3 является единственным, который имеет другой хэш-код? Другие объявляют и управляют одной и той же переменной?
class Program { static void Main(string[] args) { Calcu8(); } static void Calcu1() { int single; for (int i = 0; i < 10; i ) { single = 5; Console.WriteLine(single i); } } //Method Calcu2 has the same code as Method Calcu1 in ILSpy static void Calcu2() { for (int i = 0; i < 10; i ) { int single = 5; Console.WriteLine(single i); } } //class type static void Calcu3() { for (int i = 0; i < 10; i ) { Student stu = new Student(); stu.Name = "Tim"; //not the same Console.WriteLine(stu.GetHashCode()); } } //class type static void Calcu4() { Student stu = new Student(); for (int i = 0; i < 10; i ) { stu.Name = "Tim"; //same Console.WriteLine(stu.GetHashCode()); } } //string static void Calcu5() { string str = string.Empty; for (int i = 0; i < 10; i ) { str = "Hello"; //same Console.WriteLine(str.GetHashCode()); } } //string static void Calcu6() { for (int i = 0; i < 10; i ) { string str = string.Empty; str = "Hello"; //same Console.WriteLine(str.GetHashCode()); } } //struct static void Calcu7() { Person per = new Person(); for (int i = 0; i < 10; i ) { per.Name = "Tim"; //same Console.WriteLine(per.GetHashCode()); } } //struct static void Calcu8() { for (int i = 0; i < 10; i ) { Person per = new Person { Name = "Tim" }; //same Console.WriteLine(per.GetHashCode()); } }
}
открытый класс Student {имя открытой строки; }
публичная структура Person { имя публичной строки; }
Комментарии:
1. Поскольку код с типом значения оптимизируется, а со ссылочным типом — нет, он работает по-разному с созданием экземпляра
new Student()
один раз и в теле цикла. Таким образом, существует разница между 1 экземпляром и 10 экземплярами.struct
не по типу-ref, и он ведет себя так же, какint
здесь.
Ответ №1:
Во-первых, позвольте мне указать на разницу между вашими методами:
Метод Calcu1
, Calcu4
, Calcu5
Calcu7
: переменная была объявлена снаружи и установлена внутри цикла. Значение будет присутствовать вне цикла.
Метод Calcu2
, Calcu3
, Calcu6
Calcu8
: Переменная была объявлена внутри цикла и не будет доступна снаружи.
Ваш хэш-код Calcu3
меняется, потому что вы создаете каждый раз другой объект. При создании Student
через new стек будет иметь ссылку на новый объект в куче. Эта ссылка меняется каждый раз, потому что вы создаете 10 новых объектов.
Ваш хэш-код Calcu8
отличается, потому что это a struct
, а структуры сохраняются в куче.
Смотрите здесь для получения дополнительной информации о stack an heap. На этой стороне вы также найдете определение того, что хранится в куче и в стеке.
В стеке:
«Вещи», объявленные в следующем списке объявлений типов, являются типами значений (поскольку они взяты из System.ValueType): bool, byte, char, decimal, double, enum, float, int, long, sbyte, short, struct, uint, ulong, ushort
В куче:
«Вещи», объявленные в следующем списке объявлений типов, являются ссылочными типами (и наследуются от System.Объект… за исключением, конечно, объекта, которым является System.Объект object): класс, интерфейс, делегат, объект, строка
Комментарии:
1. Большое спасибо, братан. Но у меня все еще есть пара вопросов. 1.Хэш-код Calcu8 в моем тесте тот же, а также подтверждается вашими словами «потому что это структура, а структуры сохраняются в куче». 2. Почему ValueType не может сохраняться в куче снова и снова в цикле for?
2. Типы значений могут быть размещены в стеке или куче. Ссылочные типы не могут быть выделены стеком.