<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
假設:TSub是TParent的子類。
協變:如果一個泛型介面IFoo<T>,IFoo<TSub>可以轉換為IFoo<TParent>的話,我們稱這個過程為協變,IFoo支援對引數T的協變。
逆變:如果一個泛型介面IFoo<T>,IFoo<TParent>可以轉換為IFoo<TSub>的話,我們稱這個過程為逆變,IFoo支援對引數T的逆變。
通常只有具備繼承關係的物件才可以發生隱式型別轉換,如Base b=new sub()。
協變和逆變可以使得更多的型別之間能夠實現隱式型別轉換、型別安全性有了保障。
基於以上原因的同時、許多介面僅僅將型別引數用於引數或返回值。所以支援協變和逆變後泛型的使用上有了更大的靈活性
“TParent不能安全轉換成TSub”,是這兩個問題的共同原因。
我們定義一個介面IFoo。
interface IFoo<T> { void Method1(T param); T Method2(); }
我們看一下協變的過程:IFoo<TSub>轉換成IFoo<TParent>。
所以支援協變的引數只能用在方法的返回值中。
再看一下逆變的過程:IFoo<TParent>轉換成IFoo<TSub>。
所以支援逆變的引數只能用在方法的引數中。
這其實是對3個問題的補充。
定義一個介面IFoo,既不支援協變,也不支援逆變。
interface IFoo<T> { void Method1(T param); T Method2(); }
實現介面IFoo
public class FooClass<T> : IFoo<T> { public void Method1(T param) { Console.WriteLine(default(T)); } public T Method2() { return default(T); } }
定義一個介面IBar支援對引數T的協變
interface IBar<out T> { T Method(); }
實現介面IBar
public class BarClass<T> : IBar<T> { public T Method() { return default(T); } }
定義一個介面IBaz支援對引數T的逆變
interface IBaz<in T> { void Method(T param); }
實現介面IBaz
public class BazClass<T> : IBaz<T> { public void Method(T param) { Console.WriteLine(param.ToString()); } }
定義兩個有繼承關係的型別,IParent和SubClass。
interface IParent { void DoSomething(); } public class SubClass : IParent { public void DoSomething() { Console.WriteLine("SubMethod"); } }
按照協變的邏輯,分別來使用IFoo和IBar。
//IFoo 不支援對引數T的協變 IFoo<SubClass> foo_sub = new FooClass<SubClass>(); IFoo<IParent> foo_parent = foo_sub;//編譯錯誤 //IBar 支援對引數T的協變 IBar<SubClass> bar_sub = new BarClass<SubClass>(); IBar<IParent> bar_parent = bar_sub;
foo_parent = foo_sub 會提示編譯時錯誤“無法將型別“IFoo<SubClass>”隱式轉換為“IFoo<IParent>”。存在一個顯式轉換(是否缺少強制轉換?)”
按照逆變的邏輯,分別來使用IFoo和IBaz。
//IFoo 對引數T逆變不相容 IFoo<IParent> foo_parent = null; IFoo<SubClass> foo_sub = foo_parent;//編譯錯誤 //IBaz 對引數T逆變相容 IBaz<IParent> baz_parent = null; IBaz<SubClass> baz_sub = baz_parent;
foo_sub = foo_parent 會提示編譯時錯誤“無法將型別“IFoo<IParent>”隱式轉換為“IFoo<ISub>”。存在一個顯式轉換(是否缺少強制轉換?)”
2.0中的定義:
public interface IEnumerable<T> : IEnumerable { IEnumerator<T> GetEnumerator(); }
4.0中的定義:
public interface IEnumerable<out T> : IEnumerable { IEnumerator<T> GetEnumerator(); }
可以看到4.0中增加了對協變的支援。
可以在兩個版本試下, 下面的語句在2.0下會報錯。
List<SubClass> subarr = new List<SubClass>(); IEnumerable<IParent> parentarr = subarr;
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45