第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

重寫方法上的C#可選參數(shù)

重寫方法上的C??蛇x參數(shù)

阿波羅的戰(zhàn)車 2019-11-13 13:47:10
似乎在.NET Framework中,重寫該方法時(shí),可選參數(shù)存在問(wèn)題。以下代碼的輸出是:“ bbb”“ aaa”。但是我期望的輸出是:“ bbb”“ bbb”。是否有針對(duì)此的解決方案。我知道可以通過(guò)方法重載來(lái)解決,但想知道這樣做的原因。該代碼在Mono中也可以正常工作。class Program{    class AAA    {        public virtual void MyMethod(string s = "aaa")        {            Console.WriteLine(s);        }        public virtual void MyMethod2()        {            MyMethod();        }    }    class BBB : AAA    {        public override void MyMethod(string s = "bbb")        {            base.MyMethod(s);        }        public override void MyMethod2()        {            MyMethod();        }    }    static void Main(string[] args)    {        BBB asd = new BBB();        asd.MyMethod();        asd.MyMethod2();    }}
查看完整描述

3 回答

?
慕碼人8056858

TA貢獻(xiàn)1803條經(jīng)驗(yàn) 獲得超6個(gè)贊

這里需要注意的一件事是,每次都會(huì)調(diào)用覆蓋的版本。將替代更改為:


public override void MyMethod(string s = "bbb")

{

  Console.Write("derived: ");

  base.MyMethod(s);

}

輸出為:


derived: bbb

derived: aaa

類中的方法可以執(zhí)行以下一項(xiàng)或多項(xiàng)操作:


它定義了其他代碼調(diào)用的接口。

它定義了一個(gè)在調(diào)用時(shí)執(zhí)行的實(shí)現(xiàn)。

它可能不會(huì)兩者都做,因?yàn)槌橄蠓椒ㄖ粫?huì)做前者。


在BBB調(diào)用MyMethod()調(diào)用方法定義在AAA。


由于中存在覆蓋BBB,因此調(diào)用該方法將導(dǎo)致實(shí)現(xiàn)BBB被調(diào)用。


現(xiàn)在,中的定義AAA將兩件事告知調(diào)用代碼(嗯,還有一些無(wú)關(guān)緊要的地方)。


簽名void MyMethod(string)。

(對(duì)于支持該語(yǔ)言的語(yǔ)言)單個(gè)參數(shù)的默認(rèn)值為"aaa",因此,MyMethod()如果在找不到該方法匹配的形式的形式的代碼時(shí)MyMethod(),可以用對(duì)MyMethod(“ aaa”)的調(diào)用來(lái)替換它。

因此,這就是調(diào)用的BBB作用:編譯器看到對(duì)的調(diào)用MyMethod(),未找到方法,MyMethod()但確實(shí)找到了方法MyMethod(string)。它還可以看到在定義它的地方有一個(gè)默認(rèn)值“ aaa”,因此在編譯時(shí)它將其更改為對(duì)的調(diào)用MyMethod("aaa")。


從內(nèi)部BBB,即使在中被覆蓋,也AAA被認(rèn)為AAA是定義方法的地方BBB,以便可以覆蓋它們。


在運(yùn)行時(shí),MyMethod(string)使用參數(shù)“ aaa”調(diào)用。因?yàn)榇嬖谝粋€(gè)覆蓋的形式,所以該形式被調(diào)用,但是不使用“ bbb”來(lái)調(diào)用它,因?yàn)樵撝蹬c運(yùn)行時(shí)實(shí)現(xiàn)無(wú)關(guān),而與編譯時(shí)定義無(wú)關(guān)。


添加this.更改將檢查哪個(gè)定義,從而更改調(diào)用中使用的參數(shù)。


編輯:為什么這對(duì)我來(lái)說(shuō)似乎更直觀。


就個(gè)人而言,由于我所說(shuō)的是直觀的東西,因此只能是個(gè)人的,我發(fā)現(xiàn)它更直觀,原因如下:


如果我正在編碼,BBB那么無(wú)論是調(diào)用還是覆蓋MyMethod(string),我都認(rèn)為這是“正在做的AAA事情”,這是BBB在“正在做的AAA事情” 上做的事情,但實(shí)際上AAA都是在做事情。因此,無(wú)論是調(diào)用還是覆蓋,我都將意識(shí)到它就是AAA定義的事實(shí)MyMethod(string)。


如果我要調(diào)用使用過(guò)的代碼BBB,我會(huì)想到“使用BBB東西”。我可能不太了解最初是在中定義的AAA,因此我可能會(huì)認(rèn)為這只是實(shí)現(xiàn)細(xì)節(jié)(如果我也沒(méi)有使用AAA附近的接口)。


編譯器的行為符合我的直覺(jué),這就是為什么當(dāng)初讀這個(gè)問(wèn)題時(shí),我覺(jué)得Mono有一個(gè)錯(cuò)誤。經(jīng)考慮,我看不到任何一個(gè)如何比另一個(gè)更好地實(shí)現(xiàn)指定的行為。


盡管如此,盡管如此,在保持個(gè)人水平的同時(shí),我絕不會(huì)將可選參數(shù)與抽象,虛擬或覆蓋的方法一起使用,并且如果覆蓋了別人的方法,我會(huì)匹配它們的。


查看完整回答
反對(duì) 回復(fù) 2019-11-13
?
慕的地10843

TA貢獻(xiàn)1785條經(jīng)驗(yàn) 獲得超8個(gè)贊

您可以通過(guò)以下方式消除歧義:


this.MyMethod();

(在中MyMethod2())


它是否是一個(gè)漏洞是棘手的。它看起來(lái)確實(shí)不一致。Resharper會(huì)警告您根本不要更改覆蓋中的默認(rèn)值,如果這樣做會(huì)有所幫助; p當(dāng)然,resharper 還會(huì)告訴您this.多余,并愿意為您刪除它……這會(huì)改變行為-因此,resharper也并不完美。


看起來(lái)確實(shí)有可能成為編譯器錯(cuò)誤,我將授予您。我需要看真仔細(xì),以確保...這里的埃里克·當(dāng)你需要他,是吧?


編輯:


這里的重點(diǎn)是語(yǔ)言規(guī)范;讓我們看看第7.5.3節(jié):


例如,用于方法調(diào)用的候選集不包括標(biāo)記為重寫的方法(第7.4節(jié)),并且如果派生類中的任何方法均適用(第7.6.5.1節(jié)),則基類中的方法也不是候選者。


(實(shí)際上,第7.4節(jié)顯然沒(méi)有override考慮方法)


這里有一些沖突...。它指出如果派生類中有適用的方法,則不使用基本方法-這將導(dǎo)致我們進(jìn)入派生方法,但與此同時(shí),它表示標(biāo)記override的方法沒(méi)有考慮過(guò)的。


但是,第7.5.1.1節(jié)指出:


對(duì)于在類中定義的虛擬方法和索引器,參數(shù)列表是從函數(shù)成員的最特定的聲明或重寫中選取的,從接收方的靜態(tài)類型開(kāi)始,并搜索其基類。


然后第7.5.1.2節(jié)解釋了在調(diào)用時(shí)如何評(píng)估值:


在函數(shù)成員調(diào)用(第7.5.4節(jié))的運(yùn)行時(shí)處理期間,參數(shù)列表的表達(dá)式或變量引用按從左到右的順序求值,如下所示:


...(剪斷)...


當(dāng)從具有相應(yīng)可選參數(shù)的函數(shù)成員中省略參數(shù)時(shí),將隱式傳遞函數(shù)成員聲明的默認(rèn)參數(shù)。由于這些參數(shù)始終是恒定的,因此它們的評(píng)估不會(huì)影響其余參數(shù)的評(píng)估順序。


這明確突出表明它正在查看參數(shù)列表,該列表先前在§7.5.1.1中定義為來(lái)自最具體的聲明或重寫。似乎這是第7.5.1.2節(jié)中提到的“方法聲明”是合理的,因此傳遞的值應(yīng)該是從最派生的值到靜態(tài)類型的值。


這可能表明:csc有一個(gè)錯(cuò)誤,并且應(yīng)該使用派生版本(“ bbb bbb”),除非它被限制(通過(guò)base.或強(qiáng)制轉(zhuǎn)換為基本類型)查看基本方法聲明(第7.6.8節(jié))。 )。


查看完整回答
反對(duì) 回復(fù) 2019-11-13
?
富國(guó)滬深

TA貢獻(xiàn)1790條經(jīng)驗(yàn) 獲得超9個(gè)贊

在我看來(lái),這似乎是個(gè)錯(cuò)誤。我相信它已被明確指定,并且其行為應(yīng)與您使用顯式this前綴調(diào)用該方法的行為相同。


我已將示例簡(jiǎn)化為僅使用單個(gè)虛擬方法,并顯示了調(diào)用了哪種實(shí)現(xiàn)以及參數(shù)值是什么:


using System;


class Base

{

    public virtual void M(string text = "base-default")

    {

        Console.WriteLine("Base.M: {0}", text);

    }   

}


class Derived : Base

{

    public override void M(string text = "derived-default")

    {

        Console.WriteLine("Derived.M: {0}", text);

    }


    public void RunTests()

    {

        M();      // Prints Derived.M: base-default

        this.M(); // Prints Derived.M: derived-default

        base.M(); // Prints Base.M: base-default

    }

}


class Test

{

    static void Main()

    {

        Derived d = new Derived();

        d.RunTests();

    }

}

因此,我們需要擔(dān)心的是RunTests中的三個(gè)調(diào)用。前兩個(gè)調(diào)用的規(guī)范的重要部分是7.5.1.1節(jié),該節(jié)討論在查找相應(yīng)參數(shù)時(shí)要使用的參數(shù)列表:


對(duì)于在類中定義的虛擬方法和索引器,參數(shù)列表是從函數(shù)成員的最特定的聲明或重寫中選取的,從接收方的靜態(tài)類型開(kāi)始,并搜索其基類。


以及7.5.1.2節(jié):


當(dāng)從具有相應(yīng)可選參數(shù)的函數(shù)成員中省略參數(shù)時(shí),將隱式傳遞函數(shù)成員聲明的默認(rèn)參數(shù)。


“相應(yīng)的可選參數(shù)”是將7.5.2關(guān)聯(lián)到7.5.1.1的位。


對(duì)于M()和this.M(),參數(shù)列表都應(yīng)該是Derived接收者的靜態(tài)類型Derived,實(shí)際上,您可以告訴編譯器將其視為編譯早期的參數(shù)列表,就好像您在中都將參數(shù)強(qiáng)制設(shè)置為一樣。調(diào)用失敗-因此調(diào)用要求參數(shù)在中具有默認(rèn)值,但隨后將其忽略!Derived.M()M()Derived


確實(shí),情況變得更糟:如果您在中提供參數(shù)的默認(rèn)值,Derived但在中將Base其設(shè)為必需,則調(diào)用 M()最終將null用作參數(shù)值。如果沒(méi)有別的,我想證明這是一個(gè)錯(cuò)誤:該null值不能來(lái)自任何有效的地方。(這是null由于它是string類型的默認(rèn)值;它始終僅將默認(rèn)值用于參數(shù)類型。)


與base.M(),它表示,該規(guī)范交易部分7.6.8 ,以及作為非虛擬行為,表達(dá)被視為((Base) this).M(); 因此,使用基本方法確定有效參數(shù)列表是完全正確的。這意味著最后一行是正確的。


只是為了使想要查看上述真正奇怪的錯(cuò)誤的人更輕松,其中使用了未在任何地方指定的值:


using System;


class Base

{

    public virtual void M(int x)

    {

        // This isn't called

    }   

}


class Derived : Base

{

    public override void M(int x = 5)

    {

        Console.WriteLine("Derived.M: {0}", x);

    }


    public void RunTests()

    {

        M();      // Prints Derived.M: 0

    }


    static void Main()

    {

        new Derived().RunTests();

    }


查看完整回答
反對(duì) 回復(fù) 2019-11-13
  • 3 回答
  • 0 關(guān)注
  • 671 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)