2012-03-29 74 views
4

我想测试一个类型是否实现了一组接口之一。C#:测试一个对象是否实现了任何一个接口列表?

ViewData["IsInTheSet"] = 
      model.ImplementsAny<IInterface1, IInterface2, IInterface3, IInterface4>(); 

我写了下面的扩展方法来处理这个。

有没有一种更可扩展的方式来编写下面的代码?我宁愿不必在仍然利用泛型的同时编写新的方法。

public static bool Implements<T>(this object obj) 
    { 
     Check.Argument.IsNotNull(obj, "obj"); 

     return (obj is T); 
    } 

    public static bool ImplementsAny<T>(this object obj) 
    { 
     return obj.Implements<T>(); 
    } 

    public static bool ImplementsAny<T,V>(this object obj) 
    { 
     if (Implements<T>(obj)) 
      return true; 
     if (Implements<V>(obj)) 
      return true; 
     return false; 
    } 

    public static bool ImplementsAny<T,V,W>(this object obj) 
    { 
     if (Implements<T>(obj)) 
      return true; 
     if (Implements<V>(obj)) 
      return true; 
     if (Implements<W>(obj)) 
      return true; 
     return false; 
    } 

    public static bool ImplementsAny<T, V, W, X>(this object obj) 
    { 
     if (Implements<T>(obj)) 
      return true; 
     if (Implements<V>(obj)) 
      return true; 
     if (Implements<W>(obj)) 
      return true; 
     if (Implements<X>(obj)) 
      return true; 
     return false; 
    } 
+0

这对于http://s.tk/review来说可能是一个更好的问题。 – 2012-03-29 00:07:52

+1

通过'typeof(InterfaceN)'存储'Type'对象,然后使用'obj.GetType()'并确定这种关系? – 2012-03-29 00:08:39

回答

5

为什么不使用类似以下内容:

public static bool ImplementsAny(this object obj, params Type[] types) 
{ 
    foreach(var type in types) 
    { 
     if(type.IsAssignableFrom(obj.GetType()) 
      return true; 
    } 

    return false; 
} 

然后,你可以这样调用它:

model.ImplementsAny(typeof(IInterface1), 
        typeof(IInterface2), 
        typeof(IInterface3), 
        typeof(IInterface4)); 
+0

使用'Type.IsAssignableFrom'确定类型是否实现接口时要小心;它不适用于'obj'是泛型类的情况。我发现这很难,所以在我的答案中已经被代码处理了。 – 2012-03-29 00:37:50

1

我检查的接口已经实现的方式是:

public static bool IsImplementationOf(this Type checkMe, Type forMe) 
{ 
    if (forMe.IsGenericTypeDefinition) 
     return checkMe.GetInterfaces().Select(i => 
     { 
      if (i.IsGenericType) 
       return i.GetGenericTypeDefinition(); 

      return i; 
     }).Any(i => i == forMe); 

    return forMe.IsAssignableFrom(checkMe); 
} 

这可能很容易扩展:

public static bool IsImplementationOf(this Type checkMe, params Type[] forUs) 
{ 
    return forUs.Any(forMe => 
    { 
     if (forMe.IsGenericTypeDefinition) 
      return checkMe.GetInterfaces().Select(i => 
      { 
       if (i.IsGenericType) 
        return i.GetGenericTypeDefinition(); 

       return i; 
      }).Any(i => i == forMe); 

     return forMe.IsAssignableFrom(checkMe); 
    }); 
} 

或者更好的是:

public static bool IsImplementationOf(this Type checkMe, params Type[] forUs) 
{ 
    return forUs.Any(forMe => checkMe.IsImplementationOf(forMe)); 
} 

警告:未经测试

然后,只需做你的类型参数typeof它们传递给在此之前。

相关问题