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>。
如何对这两个实例进行类型检查,并调用这个扩展方法?

没太看明白你的意思,你的静态方法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);
这样是编译不过去的。编译器首先要检查方法签名,保证这种调用是不可能发生的。追问

确实忘了写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)了。

参考技术A 这个问题我一点也不知道解答

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?

参考技术A 参考以下:
问题1:
在调用泛型方法的时候,需要使用明确的数据类型
问题2:
如果数据类型是结构体,那么就参照结构体是如何调用成员变量,结构体名.变量名
参考技术B

a aa = (a)Convert.ChangeType(b, typeof(a));

以上是关于c# 在不知道类型的情况下,如何判断并使用带泛型的扩展方法?的主要内容,如果未能解决你的问题,请参考以下文章

java instanceof list带泛型

java instanceof list带泛型

在不知道类型是啥的情况下调用返回泛型集合的泛型方法? C#

泛型

java 泛型的使用

如何在不知道项目泛型类型参数的情况下对作为泛型给出的列表进行浅表复制? [复制]