在泛型类型未知的对象上调用方法,除非在运行时?我应该只使用动态吗?

本文关键字:我应该 运行时 动态 未知 泛型类型 对象 方法 调用 | 更新日期: 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(它实现了某些QA<Q>),基于反射的方法代码将生成一个实现接口IWrapActUponGenericA<T>的单例。 该实现可以接受 T 类型的对象和 IActUponGenericA 的实现,并调用该实现的 Act<Q> 方法。

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

相关文章: