翻译协变性与逆变性faq

翻译协变性与逆变性FAQ阅读:177评论:1作者:甜番薯发表于2010-05-1721:48原文链接原文来自AlexandraRusina在CSharpFAQ的CovarianceandContravarianceFAQ在这篇文章我尝试回答我在论坛和文档反馈里找到的最常见的关于C#协变性和逆变性的问题。对于一篇博文来讲,这是个大话题,所以你可能会看到大量"更多信息"的链接。特别感谢EricLippert和ChrisBurrows的检阅和提供很有帮助的意见。什么是协变性(covariance)和逆变性(contravariance)[又译为"反变性"]?在C#里,协变性和逆变性使数组类型、委托类型和泛型类型参数能够隐式的引用转换。协变性保持分配兼容性(assignmentcompatibility)而逆变性反转它。下面的代码演示分配兼容性、协变性和逆变性三者间的区别。//分配兼容性。stringstr="test";//派生程度较大的对象分配到派生程度较小的对象引用objectobj=str;//协变性。IEnumerablestringstrings=newListstring();//参数类型派生程度较大的实例化对象//分配给参数类型派生程度较小的对象引用。//分配兼容性被保留。IEnumerableobjectobjects=strings;//逆变性。//假定我们有这么个方法://staticvoidSetObject(objecto){}ActionobjectactObject=SetObject;//参数类型派生程度较小的实例化对象//分配给参数类型派生程度较大的对象引用。//分配兼容性被反转。ActionstringactString=actObject;在C#里,下面的情况下支持可变性:1.数组中的协变性(从C#1.0起)2.委托中的协变性和逆变性,也称作"方法组可变性"(从C#2.0起)3.接口和委托中的泛型参数的可变性(从C#4.0起)什么是数组协变性?从C#1.0起数组就是协变的。你一直都可以这样:objectobj=newString[10];在上面的代码,我将一个string的数组分配到object的数组变量中。所以,使用比原本类型派生程度较大的类型,就是协变性。数组中的协变性被认为是"不安全"的,因为你可以这样做:obj[0]=5;此代码可以编译通过,但它在运行时会抛出一个异常,因为obj事实上是string类型的数组,不能包含int类型。什么是委托或方法组的可变性?此特性是在C#2.0中添加的。当你实例化一个委托,你给它分配的方法,其返回值类型可以比此委托的返回值类型派生程度更大(协变性)。你同样可以让其参数类型比委托的参数类型派生程度更小(逆变性)。这里是代码样例,用来说明此特性及其限制:staticobjectGetObject(){returnnull;}staticvoidSetObject(objectobj){}staticstringGetString(){return"";}staticvoidSetString(stringstr){}staticvoidMain(){//协变性。委托指定了返回值是object类型,//但是我可以为其赋一个返回string类型的方法。Funcobjectdel=GetString;//逆变性。委托指定一个string类型的参数,//但是我可以为其赋一个object类型参数的方法。Actionstringdel2=SetObject;//但是,到C#4.0为止,都还不支持泛型委托之间的隐式转换Funcstringdel3=GetString;Funcobjectdel4=del3;//C#4.0为止,这里都是编译器错误}什么是泛型参数的可变性?这是C#4.0的新特性。现在,当你创建一个泛型接口,你可以指定在不同参数类型的接口实例间是否可以有隐式转换。例如,你可以使用一个返回值类型比原本指定类型派生程度更大的方法(协变性)或参数类型派生程度更小的方法(逆变性)的接口实例。同样的规则适用于泛型委托。虽然你自己可以创建一个可变的接口和委托,但这不是这个特性的主要目的。更重要的是,Framework4中接口和委托的集合已经更新成可变的了。这里是接口更新列表:IEnumerableT(T协变)IEnumeratorT(T协变)IQueryableT(T协变)IGroupingTKey,TElement(TKey和TElement协变)IComparerT(T逆变)IEqualityComparerT(T逆变)IComparableT(T逆变)这里是委托更新列表:System命名空间的Action委托,例如,ActionTandActionT1,T2(T,T1,T2,等等是逆变)System命名空间的Func委托,例如,FuncTResult和FuncT,TResult(TResult是协变;T,T1,T2,等等是逆变)PredicateT(T是逆变)ComparisonT(T是逆变)ConverterTInput,TOutput(TInput是逆变;TOutput是协变.)估计大部分用户的多数情景都是像这样:IEnumerableObjectobjects=newListString();虽然这段代码看上去并不令人印象深刻,但它让...

1、当您付费下载文档后,您只拥有了使用权限,并不意味着购买了版权,文档只能用于自身使用,不得用于其他商业用途(如 [转卖]进行直接盈利或[编辑后售卖]进行间接盈利)。
2、本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供参考,付费前请自行鉴别。
3、如文档内容存在侵犯商业秘密、侵犯著作权等,请点击“举报”。

常见问题具体如下:

1、问:已经付过费的文档可以多次下载吗?

      答:可以。登陆您已经付过费的账号,付过费的文档可以免费进行多次下载。

2、问:已经付过费的文档不知下载到什么地方去了?

     答:电脑端-浏览器下载列表里可以找到;手机端-文件管理或下载里可以找到。

            如以上两种方式都没有找到,请提供您的交易单号或截图及接收文档的邮箱等有效信息,发送到客服邮箱,客服经核实后,会将您已经付过费的文档即时发到您邮箱。

注:微信交易号是以“420000”开头的28位数字;

       支付宝交易号是以“2024XXXX”交易日期开头的28位数字。

客服邮箱:

biganzikefu@outlook.com

所有的文档都被视为“模板”,用于写作参考,下载前须认真查看,确认无误后再购买;

文档大部份都是可以预览的,笔杆子文库无法对文档的真实性、完整性、准确性以及专业性等问题提供审核和保证,请慎重购买;

文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为依据;

如果您还有什么不清楚的或需要我们协助,可以联系客服邮箱:

biganzikefu@outlook.com

常见问题具体如下:

1、问:已经付过费的文档可以多次下载吗?

      答:可以。登陆您已经付过费的账号,付过费的文档可以免费进行多次下载。

2、问:已经付过费的文档不知下载到什么地方去了?

     答:电脑端-浏览器下载列表里可以找到;手机端-文件管理或下载里可以找到。

            如以上两种方式都没有找到,请提供您的交易单号或截图及接收文档的邮箱等有效信息,发送到客服邮箱,客服经核实后,会将您已经付过费的文档即时发到您邮箱。

注:微信交易号是以“420000”开头的28位数字;

       支付宝交易号是以“2024XXXX”交易日期开头的28位数字。

文秘专家
机构认证
内容提供者

1

确认删除?