Яка різниця між System.Type та System.RuntimeType у C #?


89

Сьогодні я намагався виконати деякі конвенційні тести і отримати всі типи в збірці (за допомогою виклику Assembly.GetTypes()), коли щось натрапив:

System.RuntimeType:[First.Namespace.FirstClass]

Щоразу, коли я намагаюся порівняти цей тип typeof(FirstClass), вони не рівні. Отже, коли я намагаюся знайти всі типи, які містять FirstClassяк загальний параметр, я не знаходжу жодного.

Яка різниця між System.RuntimeTypeта System.Type?

Чи є спосіб вирішити мою проблему?


6
Чи можете ви надати невеличку програму, яка демонструє проблему, з якою ви стикаєтесь?
Ерік Ліпперт,

Я збирався, але вже отримав відповідь: P
Едгар Гонсалес,

Відповіді:


108

System.RuntimeTypeє конкретним класом, що походить від абстрактного базового класу System.Type. Оскільки System.RuntimeTypeцей файл не є загальнодоступним, ви, як правило, стикаєтесь із його екземплярами System.Type.

Плутанина може виникнути, коли ви намагаєтесь отримати тип об'єкта і помилково зателефонувати GetType()іншому об'єкту, що представляє тип першого об'єкта, а не просто використовувати цей об'єкт безпосередньо. Потім Type.ToString()повернеться, "System.RuntimeType"коли об’єкт, до якого він викликається, представляє Тип:

string str = string.Empty;
Type strType = str.GetType();
Type strTypeType = strType.GetType();
strType.ToString();     // returns "System.string"
strTypeType.ToString(); // returns "System.RuntimeType"

Наприклад, у цьому дописі в блозі хтось намагається отримати тип стовпця в базі даних, роблячи щось подібне:

object val = reader.GetFieldType(index);
Type runtimeType = val.GetType();
PropertyInfo propInfo = runtimeType.GetProperty("UnderlyingSystemType");
Type type = (Type)propInfo.GetValue(val, null);

Оскільки val вже є об'єктом Type, val.GetType () поверне інший об'єкт Type, що представляє тип, System.RuntimeTimeоскільки це конкретний тип, що використовується для представлення об'єкта оригінального типу. Потім публікація в блозі показує деякі непотрібні фокуси на відображення, щоб отримати тип об’єкта оригінального типу, коли насправді потрібно було лише:

Type type = reader.GetFieldType(index) as Type;

Отже, якщо ваш Typeоб’єкт повідомляє, що він представляє a System.RuntimeType, переконайтесь, що ви випадково не зателефонували GetType()типу, який ви вже отримали.


Перший фрагмент коду лише перевіряє, чи об'єкт є екземпляром - Typeвін поверне true, навіть якщо ви пройдете typeof(int). Другий фрагмент коду не працює для порівняння typeof(string).GetType()та typeof(Type).
Mark Cidade

Це саме те, що я шукав! Я знайшов допис Томаса Данекера, але не Доугала Белла
Едгар Гонсалес,

1
@Mark Cidade. Добре помічений, дякую. Визначте відповідь, щоб бути більш корисним, сподіваючись, виправити будь-яку плутанину, яку я ввів, посилаючись на цю публікацію в блозі.
Ergwun,

@ Едгар Гонсалес: Цей допис у блозі, на який я посилався, насправді був досить оманливим. Будь ласка, перегляньте мою оновлену відповідь для отримання детальнішої інформації.
Ergwun,

4

Від відповіді на " Різне між System.Type і System.RuntimeType " Томаса Данеккера :

System.Type - це абстрактний базовий клас. CLR має конкретну реалізацію у внутрішньому типі System.RuntimeType. Через це typeof (рядок) .GetType () повертає RuntimeType, але typeof (Type) повертає звичайний Type. Використання методу .Equals фактично робить object.ReferenceEquals, який повертає false. Щоб отримати очікувані результати, ви можете використовувати type.IsInstanceOfType (елемент). Це також поверне true, якщо елемент похідного типу. Якщо ви хочете перевірити точний тип, повернене значення false вашого методу є бажаним результатом. Ви також можете використовувати checkType (arrayType, Type.GetType ("System.RuntimeType")), щоб перевірити RuntimeType.


1
"робить насправді" - Чи можемо ми отримати граматичну корекцію. Це як суть усього, і це не має сенсу.
N73k

2

Коротко...

    "".GetType().ToString()           == "System.String"

    "".GetType().GetType().ToString() == "System.RuntimeType"

Зараз я думаю про це, що System.Typeце базовий тип для типу, який представляє результати запиту типу об'єкта під час виконання, а саме System.RuntimeType. Отже, коли ви запитуєте тип об'єкта, як, "".GetType(), екземпляр System.TypeПовертається це нащадок, System.RuntimeType. Насправді слід очікувати, що це typeof(System.Type).GetType()повинно бути System.RuntimeTypeтакож, але я думаю, що рамки спеціально перешкоджають цій ... симетрії.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.