如何检查泛型类使用的类型

时间:2013-07-04 16:22:34

标签: c# generics

考虑从MyFaultBase派生各种类的情况。因此,当您的Web服务需要指示错误时,它会抛出FaultException<MySpecificFault>类型的异常。

捕获此异常后,如何确定FaultException<T>是否绑定到从MyFaultBase派生的类?

3 个答案:

答案 0 :(得分:3)

以全球方式:

    public class SpecificClass : BaseClass
    {
    }

    public class BaseClass
    {
    }

    public class TemplatedClass<T>
    {
    }

    static void Main(string[] args)
    {
        var templateInstance = new TemplatedClass<SpecificClass>();
        var @true = typeof (BaseClass).IsAssignableFrom(templateInstance.GetType().GetGenericArguments()[0]);

        var templateInstance2 = new TemplatedClass<int>();
        var @false = typeof (BaseClass).IsAssignableFrom(templateInstance2.GetType().GetGenericArguments()[0]);
    }

答案 1 :(得分:2)

您可以使用Type.GetGenericArguments()获取泛型类型参数。

然后您的IsExceptionBoundToType方法可能如下所示:

public static bool IsExceptionBoundToType(FaultException fe, Type checkType)
{
    bool isBound = false;
    Type feType = fe.GetType();
    if (feType.IsGenericType && feType.GetGenericTypeDefinition() == typeof(FaultException<>))
    {
        Type faultType = feType.GetGenericArguments()[0];
        isBound = checkType.IsAssignableFrom(faultType);
    }

    return isBound;
}

答案 2 :(得分:0)

据我所知,没有简单的方法来检查泛型类;可能是由于通用参数的灵活性。这是一个解决方案:

public static bool IsExceptionBoundToType(FaultException fe, Type checkType)
{
   bool isBound = false;

   // Check to see if the FaultException is a generic type.
   Type feType = fe.GetType();
   if (feType.IsGenericType && feType.GetGenericTypeDefinition() == typeof(FaultException<>))
   {
      // Check to see if the Detail property is a class of the specified type.
      PropertyInfo detailProperty = feType.GetProperty("Detail");
      if (detailProperty != null)
      {
         object detail = detailProperty.GetValue(fe, null);
         isBound = checkType.IsAssignableFrom(detail.GetType());
      }
   }

   return (isBound);
}

抓住异常并按照以下方式检查:

catch (Exception ex)
{
   if ((ex is FaultException) && IsExceptionBoundToType(ex, typeof(MyFaultBase)))
   {
      // do something
   }
}