Є важливе і тонке питання, яке жоден з них не вирішує безпосередньо. Існує два способи розгляду типу в C #: статичний тип і тип роботи .
Статичний тип - це тип змінної у вихідному коді. Отже, це концепція під час компіляції. Цей тип ви бачите в підказці під час наведення курсора на змінну чи властивість у вашому середовищі розробки.
Ви можете отримати статичний тип, написавши допоміжний загальний метод, щоб дозволити виводу типу подбати про нього:
Type GetStaticType<T>(T x) { return typeof(T); }
Тип виконання - це тип об'єкта в пам'яті. Отже, це концепція часу виконання. Це тип, що повертається GetType()методом.
Тип виконання об'єкта часто відрізняється від статичного типу змінної, властивості або методу, який зберігає або повертає його. Наприклад, ви можете мати такий код:
object o = "Some string";
Статичним типом змінної є object, але під час виконання тип референтом змінної є string. Отже, наступний рядок надрукує "System.String" на консолі:
Console.WriteLine(o.GetType()); // prints System.String
Але, якщо ви наведете курсор на змінну oу своєму середовищі розробки, ви побачите тип System.Object(або еквівалентне objectключове слово). Ви також бачите те саме, використовуючи нашу допоміжну функцію зверху:
Console.WriteLine(GetStaticType(o)); // prints System.Object
Для змінного значення типу, такі як int, double, System.Guid, ви знаєте , що тип у час виконання завжди буде таким же , як статичні, так як типи значень не можуть служити в якості базового класу для іншого типу; тип значення гарантовано є найбільш похідним типом у своєму ланцюжку успадкування. Це також справедливо для закритих типів посилань: якщо статичний тип є герметичним посиланням, значення часу виконання повинно бути або екземпляром цього типу, або null.
І навпаки, якщо статичний тип змінної є абстрактним, то гарантується, що статичний тип і тип виконання будуть відрізнятися.
Щоб проілюструвати це в коді:
// int is a value type
int i = 0;
// Prints True for any value of i
Console.WriteLine(i.GetType() == typeof(int));
// string is a sealed reference type
string s = "Foo";
// Prints True for any value of s
Console.WriteLine(s == null || s.GetType() == typeof(string));
// object is an unsealed reference type
object o = new FileInfo("C:\\f.txt");
// Prints False, but could be true for some values of o
Console.WriteLine(o == null || o.GetType() == typeof(object));
// FileSystemInfo is an abstract type
FileSystemInfo fsi = new DirectoryInfo("C:\\");
// Prints False for all non-null values of fsi
Console.WriteLine(fsi == null || fsi.GetType() == typeof(FileSystemInfo));
int