C#类及其子类怎么作为泛型传递 20

如图,类MultiBorrowTag和BlackListTag为BaseQueryInfo的子类,如何让这个不报错... 如图,类MultiBorrowTag和BlackListTag为BaseQueryInfo的子类,如何让这个不报错 展开
 我来答
JINLegend
2018-10-17 · TA获得超过802个赞
知道小有建树答主
回答量:241
采纳率:100%
帮助的人:128万
展开全部

在C#里,普通类和抽象类不支持【协变】,想要用协变得用【接口】。

所谓【协变】,比如有接口IA,及其子类AA

IA<BaseQueryInfo> a=new AA<MultiBorrowTag>(...) //OK,正确的协变。

AA<BaseQueryInfo> a=new AA<MultiBorrowTag>(...) //错误,不允许协变!

协变接口的定义:

interface IA<out T> //这个out很重要,表示这个接口支持协变。

{

void F(); //OK

T G();//OK,协变允许泛型形参作为返回值。

void H(T t);//错误,协变不允许泛型形参作为函数形参。

}

所以,解决方案一:在声明DataTagEnumQueryDict变量时,用DataProcessEntity的【声明了out的父接口】代替。比如假定有个接口IDataProcess<out T>

则声明为:

private static Dictionary<DataTagEnum, IDataProcess<BaseQueryInfo>> DataTagEnumQueryDict = new ...

解决方案二:

如果类DataProcessEntity压根不存在声明了out的父接口怎么办?没办法,只能都new DataProcessEntity<BaseQueryInfo> {...}

解决方案三:如果你又不想new DataProcessEntity<BaseQueryInfo> {...},怎么办?也有一种比较曲折的方法:

自己定义一个接口!

interface IDataProcessEntityDelegator<out T>

{

void AAA();//把想要用的DataProcessEntity的方法签名原样抄下来,但千万不要抄将T用作方法形参的。

T BBB();

....

}

再定义

class DataProcessEntityDelegator<T>

{

private readonly DataProcessEntity entity;

public DataProcessEntityDelegator<out T>(A a, B b, C c.....)

{

entity=new DataProcessEntity(a,b,c.....);

}

public void AAA() =>entity.AAA();

public T BBB() = > entity.BBB();//注:这是C#6.0以后的简写语法,否则自己写完整的函数体。

}

然后你就可以快乐的在代码里写:

private static Dictionary<DataTagEnum, IDataProcessEntityDelegator<BaseQueryInfo>> DataTagEnumQueryDict = new ...

......

DataTagEnumQueryDict.Add(... ,DataProcessEntityDelegator<BaseQueryInfo>{......} );

DataTagEnumQueryDict.Add(... ,DataProcessEntityDelegator<MultiBorrowTag>{......} );

DataTagEnumQueryDict.Add(... ,DataProcessEntityDelegator<BlackListTag>{......} );

用哪种方法就看你的觉悟了

更多追问追答
追问
测试了一下第3、4行,好像没有问题啊,可以正常使用
追答
没道理啊,普通类是不能支持协变和逆变,只有接口和委托可以拥有可变的类型参数。你测试的是具体哪一句啊?
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式