c# 在不知道类型的情况下,如何判断并使用带泛型的扩展方法?
业务情景是这样的:已知两个接口::publicinterfaceIA{}publicinterfaceIB{}已知三个泛型类:publicclassCa<T>:IA{}p...
业务情景是这样的:
已知两个接口::
public interface IA{}
public interface IB{}
已知三个泛型类 :
public class Ca<T>:IA{}
public class Cb<T>:IB{}
public class Cc<T>{}
以及已知一个扩展方法:
public static class XXXExtension
{
public static Cc<T> CalculateC<T> (this Ca<T> ca,Cb<T> cb)
{ ... }
}
现在我通过反射拿到了IA,IB的两个实例,(不能保证就是Ca<>和Cb<>,就算两个是Ca<>和Cb<>,也不能保证用的是同一个泛型参数)。
业务要求是: 如果它们是用同一个泛型参数T的 Ca<T> 和 Cb<T> ,就计算出Cc<T>。
如何对这两个实例进行类型检查,并调用这个扩展方法? 展开
已知两个接口::
public interface IA{}
public interface IB{}
已知三个泛型类 :
public class Ca<T>:IA{}
public class Cb<T>:IB{}
public class Cc<T>{}
以及已知一个扩展方法:
public static class XXXExtension
{
public static Cc<T> CalculateC<T> (this Ca<T> ca,Cb<T> cb)
{ ... }
}
现在我通过反射拿到了IA,IB的两个实例,(不能保证就是Ca<>和Cb<>,就算两个是Ca<>和Cb<>,也不能保证用的是同一个泛型参数)。
业务要求是: 如果它们是用同一个泛型参数T的 Ca<T> 和 Cb<T> ,就计算出Cc<T>。
如何对这两个实例进行类型检查,并调用这个扩展方法? 展开
2个回答
展开全部
没太看明白你的意思,你的静态方法CalculateC(首先这不是你所谓的“扩展方法”,它没有对第一个参数使用this)在声明中就已经限制了传入的两个参数必须是针对同一个泛型参数T的,也就是说,你可以这样调用
Ca<int> ca = new Ca<int>();
Cb<int> cb = new Cb<int>();
Cc<int> cc = XXXExtension.CalculateC<int>(ca,bc);
现在你得到的自然就是Cc<int>类型的cc呀。
你并不可能使用不同的泛型参数,如:
Ca<int> ca = new Ca<int>();
Cb<string> cb = new Cb<string>();
然后你想要:
Cc<int> cc = XXXExtension.CalculateC<int>(ca,bc);
或者
Cc<string> cc = XXXExtension.CalculateC<string>(ca,bc);
甚至
Cc<decimal> cc = XXXExtension.CalculateC<decimal>(ca,bc);
这样是编译不过去的。编译器首先要检查方法签名,保证这种调用是不可能发生的。
Ca<int> ca = new Ca<int>();
Cb<int> cb = new Cb<int>();
Cc<int> cc = XXXExtension.CalculateC<int>(ca,bc);
现在你得到的自然就是Cc<int>类型的cc呀。
你并不可能使用不同的泛型参数,如:
Ca<int> ca = new Ca<int>();
Cb<string> cb = new Cb<string>();
然后你想要:
Cc<int> cc = XXXExtension.CalculateC<int>(ca,bc);
或者
Cc<string> cc = XXXExtension.CalculateC<string>(ca,bc);
甚至
Cc<decimal> cc = XXXExtension.CalculateC<decimal>(ca,bc);
这样是编译不过去的。编译器首先要检查方法签名,保证这种调用是不可能发生的。
追问
确实忘了写this,不过与问题无关紧要,我的问题点是我通过反射拿到的两个实例不能保证就是Ca和Cb,并且也不能保证用的是同一个泛型参数。但情景要求是如果满足条件,就要对他们进行下一步计算,请问该如何实现?
追答
好吧,既然你的CalculateC<T>是扩展方法,那么如果你要调用
ca.CalculateC(cb),编译器首先就要能确定ca的类型是Ca<T>,否则编译不过去,这就是说,你可以有两个办法来检查以确保类型匹配:
如果你明确知道泛型T应该是什么类型(如int),那么你可以用
if(ca is Ca<int>)
来检查ca是不是Ca<int>,或使用
Ca<int> caTemp = ca as Ca<int>;并检查caTemp是否为空。
如果你真的什么都不知道,就是想确定拿到的ca到底是不是Ca<T>(不知道T是什么类型),就麻烦一点:
首先看ca是不是Ca<T>:
if (ca.GetType().Name == typeof(Ca<int>).Name)
由于泛型类的名称是一样的,所以你对比Ca<int>就可以判断出ca是不是Ca<T>;
如果是的话,再判断泛型类型T是什么:
string genericName = ca.GetType().GenericTypeArguments.First().Name
同理你可以拿到cb的泛型类型名称,如果是同一类型,就可以调用ca.CalculateC(cb)了。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询