c# 在不知道类型的情况下,如何判断并使用带泛型的扩展方法?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c# 在不知道类型的情况下,如何判断并使用带泛型的扩展方法?相关的知识,希望对你有一定的参考价值。
业务情景是这样的:
已知两个接口::
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>。
如何对这两个实例进行类型检查,并调用这个扩展方法?
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)了。
C#泛型参数的数据结构还原?
定义了一个多字段的结构
struct a
public int ai;
public string as;
public float af;
定义了一个泛型方法
public bool Test<T>(string a, T b)
//当传入参数是数据类型为a的变量时,我要引用其成员ai、as、af该如何操作?
当调用时,如果参数T b是某个类型为a的变量b,
1.如何判断传入参数数据类型?
2.如果传入数据类型为a,我如何引用b.ai、b.as、b.af?
问题1:
在调用泛型方法的时候,需要使用明确的数据类型
问题2:
如果数据类型是结构体,那么就参照结构体是如何调用成员变量,结构体名.变量名 参考技术B
a aa = (a)Convert.ChangeType(b, typeof(a));
以上是关于c# 在不知道类型的情况下,如何判断并使用带泛型的扩展方法?的主要内容,如果未能解决你的问题,请参考以下文章