0

说我有课

public abstract class A<T>
{
     public T GetT{get;}

     public ISomeInterface AMethod{get;}
}

然后我在另一个类中有一些其他方法,我在其中获取一个对象,我想检查它的类型,A<> 然后如果它是获取类型T并调用方法AMethod。所以我这样做:

if (theObject.GetType().GetGenericTypeDefinition() == typeof (A<>))
{
    Type TType = theObject.GetType().GetGenericArguments()[0];            
    dynamic dynamicObject= theObject;
    ISomeInterface filter = dynamicObject.AMethod;
    //...some other stuff using TType
} 

有没有办法在不使用动态对象的情况下做到这一点,因为我不能在运行时使用TType或使用泛型类型定义来声明变量的类型A<>......

4

2 回答 2

4

如果可以的话,将所有非泛型的东西放在一个抽象的非泛型基类中:

public abstract class A
{
     public ISomeInterface AMethod{get;}
}

public abstract class A<T> : A
{
     public T GetT{get;}
}

然后你可以使用:

A foo = theObject as A;
if (foo != null)
{
    ISomeInterface filter = foo.AMethod;
}
于 2012-05-31T15:22:08.013 回答
1

正如 Skeet 先生所提到的,将不依赖于类类型的项目拉入非泛型类或接口通常是实际可行的方法。否则,我建议使用类型参数编写一个泛型方法,T该方法将返回一个泛型单例(通过反射生成),该方法可以将对象传递给具有参数类型的泛型方法,U例如T:A<U>. 这样的方法只需要对任何特定类型使用反射一次T,无论它用于处理该类型的实例多少次。

因为委托只能与封闭的泛型一起使用,所以可能必须定义一些泛型接口:

// 用户代码将为调度提供这些接口之一的实现
// 对象,它将以适当的类型调用其“Act”方法
接口 IActUponGenericA
{
  void Act<T>(A<T> 参数);
}
接口 IActUponGenericA<PT1>
{
  void Act<T>(A<T> 参数, PT1 extraParam1);
}
接口 IActUponGenericA<PT1,PT2>
{
  void Act<T>(A<T> 参数, PT1 extraParam1, PT2 extraParam2);
}
// 调度对象本身会实现这个接口:
接口 IWrapActUponGenericA<T>
{
  void CallAction(IActUponGenericA act, T param);
  void CallAction<PT1>(IActUponGenericA<PT1> act, T param, PT1 extraParam1);
  void CallAction<PT1,PT2>(IActUponGenericA<PT1,PT2> act, T param,
                             PT1 extraParam1, PT2 extraParam2);
}

然后给定一个参数类型TA<Q>为 some实现Q),基于反射的方法代码将生成一个实现 interface 的单例IWrapActUponGenericA<T>。该实现可以采用 类型的对象T和 的实现IActUponGenericA,并调用该实现的Act<Q>方法。

这种方法将比使用更复杂dynamic,并且可能会或可能不会表现更好;但是,它将能够处理一些不能处理的情况dynamic

于 2012-05-31T16:30:25.000 回答