欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#中的協(xié)變與逆變小結(jié)

 更新時(shí)間:2021年10月27日 12:19:38   作者:Hello Bug.  
這篇文章主要介紹了C#中的協(xié)變與逆變的相關(guān)知識(shí),在泛型或委托中,如果不使用協(xié)變或逆變,那么泛型類型是一個(gè)固定類型,而使用協(xié)變或逆變的話,則泛型類型可以實(shí)現(xiàn)多態(tài)化,需要的朋友可以參考下

一:什么是協(xié)變與逆變

協(xié)變指能夠使用比原始指定的派生類型的派生程度更大(更具體的)的類型,逆變指能夠使用比原始指定的派生類型的派生程度更?。ú惶唧w的)的類型

只有泛型接口和泛型委托參數(shù)支持協(xié)變和逆變

二:引言

using System;
using System.Collections.Generic;
 
class MainClass
{
    static void Main()
    {
        object o = "str";
        List<object> oList = new List<string>();
        IEnumerable<object> strs = new List<string>();
    }
}

上面這段代碼中,第一句沒(méi)問(wèn)題,屬于類型安全轉(zhuǎn)換,第二句會(huì)報(bào)錯(cuò),因?yàn)檫@兩個(gè)list并沒(méi)有繼承關(guān)系,而第三句是正確的,其實(shí)在背后,就是協(xié)變和逆變?cè)谄鹱饔?/p>

三:協(xié)變

協(xié)變?cè)诜盒头椒ǖ膮?shù)里以out表示,使用out可以在聲明父類泛型參數(shù)的時(shí)候使用子類泛型參數(shù)構(gòu)造,out參數(shù)可以單純的理解為輸出,作為返回值例如IEnumerable<T>接口

using System;
using System.Collections.Generic;
 
class MainClass
{
    static void Main()
    {
        IEnumerable<object> list = new List<string>();
    }
}

分析一下上面的代碼為什么是合法的呢?首先雖然是用IEnumerable<object>聲明的,但是是用List<string>構(gòu)造的,列表中的元素是string類型。其次IEnumerable的作用只有遍歷元素,不允許添加操作,所以是合法的,本質(zhì)上就是里氏替換原則

四:逆變

逆變?cè)诜盒头椒ǖ膮?shù)里以in表示,使用in可以在聲明子類泛型參數(shù)的時(shí)候使用父類泛型參數(shù)構(gòu)造,int參數(shù)只能作為傳入值不能作為返回值例如Action<T>委托

using System;
 
class MainClass
{
    static void Main()
    {
        Action<string> action = new Action<object>((o)=> { });
        action("");
    }
}

分析一下上面的代碼為什么是合法的呢?看似是object轉(zhuǎn)換成了string,但實(shí)際上使用委托的時(shí)候傳入的是一個(gè)string類型的參數(shù),然后將string轉(zhuǎn)換成了object,本質(zhì)上還是派生類到基類的轉(zhuǎn)換,所以是類型安全的,本質(zhì)上就是里氏替換原則

五:為什么協(xié)變和逆變是針對(duì)泛型接口或泛型委托參數(shù)的?

不能針對(duì)泛型類?

由上可知,協(xié)變和逆變都是定義方法成員的(接口不能定義字段只能定義成員),而方法成員在創(chuàng)建對(duì)象時(shí)是不涉及到對(duì)象內(nèi)存分配的,所以是類型安全的,而泛型類是模板類,類中可以包含字段, 所以是不安全的

using System;
using System.Collections.Generic;
 
class MainClass
{
    static void Main()
    {
        object o1 = "";//類型安全
        string s1 = (string)o1;//非類型安全
        IEnumerable<object> o2 = new List<string>();//協(xié)變
        Action<string> s2 = new Action<object>((o) => { });//逆變
    }
}

六:自定義協(xié)變

using System;
using System.Collections.Generic;
 
class MainClass
{
    static void Main()
    {
        ICustomCovariant<object> o = new CustomCovariant<string>();
    }
}
 
public interface ICustomCovariant<out T>
{
    T Get();
}
public class CustomCovariant< T> : ICustomCovariant<T>
{
    public T Get()
    {
        return default(T);
    }
}

七:自定義逆變

using System;
using System.Collections.Generic;
 
class MainClass
{
    static void Main()
    {
        IContravariant<string> o = new CustomContravariant<object>();
    }
}
 
public interface IContravariant<in T>
{
    void Get(T t);
}
public class CustomContravariant<T> : IContravariant<T>
{
    public void Get(T t)
    {
 
    }
}

八:總結(jié)

——在泛型中,如果確定泛型參數(shù)是只讀或者只寫的,那么就可以使用協(xié)變或者逆變。如果泛型參數(shù)無(wú)法確定只讀或只寫,這種類型參數(shù)既不能協(xié)變也不能逆變,只能精確類型匹配 ——在泛型或委托中,如果不使用協(xié)變或逆變,那么泛型類型是一個(gè)固定類型,而使用協(xié)變或逆變的話,則泛型類型可以實(shí)現(xiàn)多態(tài)化

到此這篇關(guān)于C#中的協(xié)變與逆變的文章就介紹到這了,更多相關(guān)C#協(xié)變與逆變內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Unity?數(shù)據(jù)存儲(chǔ)和讀取的方法匯總

    Unity?數(shù)據(jù)存儲(chǔ)和讀取的方法匯總

    這篇文章主要介紹了Unity?數(shù)據(jù)存儲(chǔ)和讀取的方法,本文通過(guò)四種方法在 Unity 中實(shí)現(xiàn)數(shù)據(jù)存儲(chǔ)和讀取方法的案例內(nèi)容,結(jié)合示例代碼給大家講解的非常詳細(xì),需要的朋友可以參考下
    2022-10-10
  • C# Unicode編碼解碼的實(shí)現(xiàn)

    C# Unicode編碼解碼的實(shí)現(xiàn)

    本文主要介紹了C# Unicode編碼解碼的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • 詳解C#中HttpClient的用法及相關(guān)問(wèn)題的解決方法

    詳解C#中HttpClient的用法及相關(guān)問(wèn)題的解決方法

    相信大家在使用 HttpClient 的時(shí)候遇到過(guò) 遠(yuǎn)程主機(jī)強(qiáng)迫關(guān)閉了一個(gè)現(xiàn)有的連接 的錯(cuò)誤。本文就來(lái)說(shuō)說(shuō)它的解決方法以及HttpClient的正確用法,需要的可以參考一下
    2022-11-11
  • C#定義簡(jiǎn)單的反射工廠實(shí)例分析

    C#定義簡(jiǎn)單的反射工廠實(shí)例分析

    這篇文章主要介紹了C#定義簡(jiǎn)單的反射工廠的用法,實(shí)例分析了反射工廠的原理與使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-04-04
  • C#中yield用法使用說(shuō)明

    C#中yield用法使用說(shuō)明

    本文介紹了C#中yield的使用方法,yield 語(yǔ)句不能出現(xiàn)在匿名方法,其他相關(guān)內(nèi)容就仔細(xì)閱讀下文吧
    2015-10-10
  • C#獲取文件夾所占空間大小的功能

    C#獲取文件夾所占空間大小的功能

    這篇文章介紹了C#獲取文件夾所占空間大小的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • c#源碼的執(zhí)行過(guò)程詳解

    c#源碼的執(zhí)行過(guò)程詳解

    在本篇文章中給大家詳細(xì)講述了c#源碼的執(zhí)行過(guò)程,對(duì)此有需要的朋友們可以學(xué)習(xí)下。
    2018-07-07
  • C#實(shí)現(xiàn)WPF項(xiàng)目復(fù)制和移動(dòng)文件夾

    C#實(shí)現(xiàn)WPF項(xiàng)目復(fù)制和移動(dòng)文件夾

    這篇文章介紹了C#實(shí)現(xiàn)WPF項(xiàng)目復(fù)制和移動(dòng)文件夾的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • 比較2個(gè)datatable內(nèi)容是否相同的方法

    比較2個(gè)datatable內(nèi)容是否相同的方法

    這篇文章主要介紹了比較2個(gè)datatable內(nèi)容是否相同的方法,大家參考使用吧
    2014-01-01
  • WPF自定義控件實(shí)現(xiàn)ItemsControl魚眼效果

    WPF自定義控件實(shí)現(xiàn)ItemsControl魚眼效果

    這篇文章主要為大家詳細(xì)介紹了WPF如何通過(guò)自定義控件實(shí)現(xiàn)ItemsControl魚眼效果,文中的示例代碼講解詳細(xì),需要的可以參考一下
    2024-01-01

最新評(píng)論