2009-10-08 44 views
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. 
    } 
} 

有没有一种方法,以确保valueFoo类型的一些实例吗?

回答

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

我不知道你可以使用没有类型参数的泛型类型...非常好。目前,我只是担心前一种情况,但后者也很好理解。 – 2009-10-08 09:05:50

0

如果你从基类重写,我认为你不能这样做。

虽然你可以沿着这些线做些事情。最大的缺点是你会放松编译时类型检查并将其保留在运行时。

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

您可以尝试在value.GetType()调用GetGenericTypeDefinition。这基本上会给你Foo<>或抛出一个异常。为避免后者,请检查IsGenericType标志。