Подтвердить что ты не робот

Когда и где использовать GetType() или typeof()?

Почему это работает

if (mycontrol.GetType() == typeof(TextBox))
{} 

и это не?

Type tp = typeof(mycontrol);

Но это работает

Type tp = mycontrol.GetType();

Я сам использую оператор is для проверки типа, но мое понимание терпит неудачу, когда я использую typeof() и GetType()

Где и когда использовать GetType() или typeof()?

4b9b3361

Ответ 1

typeof является оператором для получения типа, известного во время компиляции (или, по крайней мере, для параметра общего типа). Операндом typeof всегда является имя параметра типа или типа - никогда не выражение со значением (например, переменной). Подробнее см. спецификацию языка С#.

GetType() - это метод, который вы вызываете для отдельных объектов, чтобы получить тип времени выполнения объекта.

Обратите внимание, что, если вам нужны только те экземпляры TextBox (а не экземпляры подклассов), вы обычно используете:

if (myControl is TextBox)
{
    // Whatever
}

или

TextBox tb = myControl as TextBox;
if (tb != null)
{
    // Use tb
}

Ответ 2

typeof применяется к имени параметра типа или универсального типа, известного во время компиляции (задается как идентификатор, а не как строка). GetType вызывается для объекта во время выполнения. В обоих случаях результатом является объект типа System.Type, содержащий метаинформацию о типе.

Пример, в котором типы времени компиляции и выполнения равны

string s = "hello";

Type t1 = typeof(string);
Type t2 = s.GetType();

t1 == t2 ==> true

Пример, в котором типы времени компиляции и выполнения различны

object obj = "hello";

Type t1 = typeof(object); // ==> object
Type t2 = obj.GetType();  // ==> string!

t1 == t2 ==> false

то есть тип времени компиляции (статический тип) переменной obj не совпадает с типом времени выполнения объекта, на который ссылается obj.


Типы тестирования

Однако, если вы хотите знать, является ли mycontrol TextBox, вы можете просто проверить

if (mycontrol is TextBox)

Обратите внимание, что это не полностью эквивалентно

if (mycontrol.GetType() == typeof(TextBox))    

потому что mycontrol может иметь тип, производный от TextBox. В этом случае первое сравнение дает true, а второе false! Первый и более простой вариант в большинстве случаев приемлем, так как элемент управления, полученный из TextBox, наследует все, что имеет TextBox, вероятно, добавляет к нему больше и, следовательно, совместим по присвоению с TextBox.

public class MySpecializedTextBox : TextBox
{
}

MySpecializedTextBox specialized = new MySpecializedTextBox();
if (specialized is TextBox)       ==> true

if (specialized.GetType() == typeof(TextBox))        ==> false

Кастинг

Если у вас есть следующий тест, за которым следует приведение, а T обнуляется...

if (obj is T) {
    T x = (T)obj; // The casting tests, whether obj is T again!
    ...
}

... вы можете изменить его на...

T x = obj as T;
if (x != null) {
    ...
}

Проверка того, имеет ли значение заданный тип, и приведение (которое снова включает этот же тест) могут занимать много времени для длинных цепочек наследования. Использование оператора as с последующим тестом для null более эффективно.

Начиная с С# 7.0, вы можете упростить код, используя сопоставление с шаблоном:

if (obj is T t) {
    // t is a variable of type T having a non-null value.
    ...
}

Кстати: это работает и для типов значений. Очень удобно для тестирования и распаковки. Обратите внимание, что вы не можете проверять типы значений, допускающие значение NULL:

if (o is int? ni) ===> does NOT compile!

Это потому, что либо значение null, либо значение int. Это работает как для int? o, так и для object o = new Nullable<int>(x);:

if (o is int i) ===> OK!

Мне это нравится, потому что это устраняет необходимость доступа к свойству Nullable<T>.Value.

Ответ 3

typeOf - это ключевое слово С#, которое используется, когда у вас есть имя класса. Он вычисляется во время компиляции и, следовательно, не может использоваться в экземпляре, который создается во время выполнения. GetType - это метод класса объекта, который может использоваться в экземпляре.

Ответ 4

Вам может быть проще использовать ключевое слово is:

if (mycontrol is TextBox)