Для аргумента, у меня есть 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
?
Хорошо, если вы хотите проверить, достаточно ли это 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
.
Вы можете попытаться вызвать GetGenericTypeDefinition на value.GetType()
. Это в основном даст вам либо Foo<>
, либо исключение. Чтобы избежать последнего, отметьте флаг IsGenericType
.
Я не думаю, что вы можете это сделать, если вы переопределяете базовый класс.
Вы могли бы сделать что-то в этом направлении. Большим недостатком является то, что вы теряете проверку типа времени компиляции и опускаете ее на время выполнения.
class Foo<T> : SomeBaseClass
{
public override MyFunction(object value)
{
if(value.GetType() != typeof(T))
{
// wrong type throw exception or similar
}
}
}