簡體   English   中英

C#虛擬方法覆蓋返回類型和方法參數

[英]C# virtual methods override the return type & method arguments

我想在抽象類中使用確切名稱初始化虛擬方法。

在類中,這是繼承者的重寫方法,我可以重寫:

  • 基本方法的返回類型
  • 方法的參數

為了向您展示,我真正想做的是這樣的:

abstract class A
{
    public virtual void Func1() { }
}

class B : A
{
    override string Func1(int a, int b)
    {
         return (a + b).ToString();
    }
}

我知道,C#需要像在基類中一樣使用返回類型/參數,但是在這種情況下也許有一些帶有關鍵字new提示?

您只能override確切的名稱和參數。 您可以new任何你想要的,但是這不重寫-只是完全匹配的情況下,藏了起來。

我認為在您的情況下,您要么想為所有可能的組合創建重載,要么創建一個單一的基本抽象方法,該方法采用可以包含所需參數的單一類型。

例:

public abstract void Func1( MyArgumentsType input );

現在,派生類被強制重寫方法,但是您可以將一組可靠的參數傳遞給該方法,以處理更多場景。

多態在這里可以為您帶來好處,因為您隨后可以將派生的參數類型傳遞給具有特定於情況的屬性的方法。 當然,這需要實現方法來了解更多派生的參數類型。

你做不到。 覆蓋方法需要具有完全相同的簽名,其中包括參數和返回類型。 您無法告訴編譯器重寫具有不同參數和返回類型的方法。

如果您想要多態行為,則需要具有兼容的簽名。 否則,編譯器無法保證所需的方法將是多態的。

沒有可以想象的方法將簽名void Func1()string Func1(int a, int b)視為多態。 你可以用它們概括out內通lambda表達式的參數,但無論如何-趁你需要把他們帶到一個共同的簽名多態行為。

of an inherited member and not it's . 方法覆蓋意味着修改繼承成員的虛擬 ,而不是其 正如您指出的那樣, new關鍵字將隱藏具有相同名稱的成員的基類的實現。 但是它只是可選的,看看這個
在與基類成員同名的派生類成員中使用new關鍵字的好處

看起來您想要實現類似於ToString方法的行為,該行為對於不同類型(例如.ToString()float.ToString("c") )具有許多不同的風格。

在這種情況下, ToString不同實現不是Object.ToString實現,而是基於參數適當解析的派生對象的常規附加方法。 所有派生類都以一個虛擬ToString方法(來自基類,並可能在當前類中實現)結束,並可選地具有其他非虛擬的類似命名的方法。

請注意,在C#結果類型中,函數解析時間考慮到了較新的函數,因此您實際上不能擁有2個具有相同名稱和參數的函數,並且期望“正確”選擇一個函數。 如果兩者同時可見,則會出現編譯時錯誤。 方法前面的new關鍵字使該方法對於該類(和派生類)僅可見,並隱藏具有相同簽名的基類方法。 不幸的是,當使用保留派生類的基類的變量來調用此方法時,這樣做幾乎保證了很多混亂-盡管所有努力都隱藏了基類,但仍將調用基類中的虛擬變量。

考慮一下...它將如何工作? 假設您有一個引用,其靜態類型為A但動態類型為B ,如下所示:

foo(B b) { bar(b); }
bar(A a) { 
}

覆蓋背后的想法是,您在super / base上調用一個方法,並且解析為覆蓋的實現。 通過這種邏輯,您應該能夠在bar中調用a.Func1() ,並且應該在B調用方法:

a.Func1(???)

但這在這里是不可能的,因為缺少參數。

有參數自變量和返回類型協方差的概念。 在SO中, 是一個有趣的答案,並鏈接到Eric Lippert的帖子,該文章應該很有趣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM