Как я могу проверить, является ли объект универсальным типом?

2

Для аргумента, у меня есть object. Я не могу изменить подпись моей функции, потому что я расширяю класс другого класса.

Чтобы дать конкретный пример, у меня есть следующее:

class Foo<T> : SomeBaseClass
{
    public override MyFunction(object value)
    {
        // TODO: Figure out if value is an instance of Foo, though I don't care
        // what type was associated with it.
    }
}

Есть ли способ убедиться, что value является экземпляром типа Foo?

Теги:

3 ответа

6
Лучший ответ

Хорошо, если вы хотите проверить, достаточно ли это Foo<something>:

Type type = value.GetType();
if (!type.IsGenericType)
{
    throw new ArgumentException("Not a generic type");
}
if (type.GetGenericTypeDefinition() != typeof(Foo<>))
{
    throw new ArgumentException("Not the right generic type");
}

Если вам нужно решить, будет ли этот тип, полученный из Foo<T>, немного сложнее, потому что вы не обязательно знаете, где он будет общим. Например, это может быть:

class Bar : Foo<string>

или

class Baz<T> : Foo<T>

Одна из альтернатив облегчить ситуацию может заключаться в том, чтобы ввести еще один не общий класс:

abstract class Foo : SomeBaseClass

class Foo<T> : Foo

Тогда вы можете просто сделать:

if (value is Foo)

Конечно, это также позволило бы другим типам получить от Foo. Во многих случаях это не будет проблемой, но это зависит от вашей конкретной ситуации. Вы также можете поместить любых членов, которым не нужно ссылаться на T на Foo, чтобы вы могли получить к ним доступ в таких случаях, где вам не важно T.

  • 0
    Я не знал, что вы можете использовать универсальный тип без такого параметра типа ... очень хорошо. На данный момент я беспокоюсь только о первом случае, но второе тоже полезно знать.
2

Вы можете попытаться вызвать GetGenericTypeDefinition на value.GetType(). Это в основном даст вам либо Foo<>, либо исключение. Чтобы избежать последнего, отметьте флаг IsGenericType.

0

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

Вы могли бы сделать что-то в этом направлении. Большим недостатком является то, что вы теряете проверку типа времени компиляции и опускаете ее на время выполнения.

class Foo<T> : SomeBaseClass
{
    public override MyFunction(object value)
    {
       if(value.GetType() != typeof(T))
       {
          // wrong type throw exception or similar
       }
    }
}  

Ещё вопросы

Сообщество Overcoder
Наверх
Меню