在泛型类型未知的对象上调用方法,除非在运行时?我应该只使用动态吗?
本文关键字:我应该 运行时 动态 未知 泛型类型 对象 方法 调用 | 更新日期: 2023-09-27 18:35:59
说我有一个类
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<>
声明变量的类型......
如果可以的话,将所有非泛型的东西放在一个抽象的非泛型基类中:
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;
}
正如 Skeet 先生所提到的,将不依赖于类类型的项目拉入非泛型类或接口通常是实用的方法。 否则,我建议编写一个带有类型参数T
的泛型方法,该方法将返回一个泛型单例(通过反射生成),可以将对象传递给具有参数类型的泛型方法U
以便T:A<U>
。 对于任何特定类型的T
,这种方法只需要使用一次反射,无论它被用来处理该类型的实例多少次。
由于委托只能与封闭泛型一起使用,因此可能必须定义一些泛型接口:
用户代码将向调度提供这些接口之一的实现对象,它将使用正确的类型调用其"Act"方法接口 IActUponGenericA{ 无效法案(A 参数);}接口 IActUponGenericA { void Act (A param, PT1 extraParam1);}接口 IActUponGenericA<PT1,PT2>{ void Act (A param, PT1 extraParam1, PT2 extraParam2);}调度对象本身将实现此接口:接口 IWrapActUponGenericA { void CallAction(IActUponGenericA act, T param); void CallAction (IActUponGenericA act, T param, PT1 extraParam1); void CallAction<PT1,PT2>(IActUponGenericA<PT1,PT2> act, T param, PT1 extraParam1, PT2 extraParam2);}
然后给定一个参数类型T
(它实现了某些Q
的A<Q>
),基于反射的方法代码将生成一个实现接口IWrapActUponGenericA<T>
的单例。 该实现可以接受 T
类型的对象和 IActUponGenericA
的实现,并调用该实现的 Act<Q>
方法。
这种方法将比使用dynamic
更复杂,并且可能会或可能不会表现得更好;但是,它将能够处理一些dynamic
无法处理的情况。