簡體   English   中英

C#如何避免泛型推送 <T> 方法與非泛型方法發生簽名沖突?

[英]C# How to avoid generic pushing <T> method into signature collision with non-generic method?

我遇到了一個我無法解決的問題。 我有一個提供方法簽名的接口。 此方法接受一個字符串,並返回布爾值。

然后,該接口由一個抽象類實現,該抽象類采用通用T型參數定義接口函數的重載版本。 此重載方法接受T並返回布爾值。 同樣,接口方法通過具體的類而不是抽象的實現被抽象出來以實現。

當具體類輸入T的字符串時,我遇到了一個問題,因為它似乎在接口方法簽名和抽象方法簽名之間引起某種沖突。 我曾嘗試尋找解決方案,但我的Google-fu讓我失敗了。

編譯時收到以下錯誤消息:

錯誤2'FooBarTest1.StringFoo'未實現繼承的抽象成員'FooBarTest1.AFoo.Bar(string)'Program.cs 41 18 ConsoleApplication1

錯誤3繼承的成員'FooBarTest1.AFoo.Bar(string)'和'FooBarTest1.AFoo.Bar(T)'在類型'FooBarTest1.StringFoo'中具有相同的簽名,因此不能覆蓋ConsoleApplication1 \\ Program.cs 43 30 ConsoleApplication1

除了更改方法名稱之一之外,還有其他解決方法嗎? (下面的示例代碼)

namespace FooBarTest1
{
    public class Program
    {
        static void Main(string[] args)
        {
            Foo f = new Foo();
        }
    }

    public interface IFoo
    {
        bool Bar(string foo);
    }

    public abstract class AFoo<T> : IFoo
    {
        public abstract bool Bar(string foo);
        public abstract bool Bar(T foo);
    }

    public class IntFoo : AFoo<int>
    {
        public override bool Bar(string foo)
        {
            return true;
        }

        public override bool Bar(int foo)
        {
            return Bar(foo.ToString());
        }
    }

    public class StringFoo : AFoo<string>
    {
        public override bool Bar(string foo)
        {
            return true;
        }
    }
}

您將不得不重命名該方法(或以其他方式更改簽名)。 問題是,如果T的類型為String ,則兩個Bar方法會發生沖突。 換句話說,當T為字符串時,您不再需要重載該方法-您正在復制該方法,這是一個錯誤。

要問的一個問題是:“ Bar的字符串實現與通用實現有何不同(特別是在通用類型是字符串的情況下)?” 如果答案是“因為...而有所不同”,則應更改名稱以反映不同的行為。

如果實現是相同的,則實現內部的邏輯應處理這種情況,並且您只需要一個帶有該簽名的方法。 換句話說,您可以僅保留帶有字符串參數的實現,然后檢查方法內部的T類型,以在需要時執行其他操作。

否則,如果您不想重命名或刪除其中之一,則可以執行以下操作:

public abstract class AFoo<T> : IFoo
{
    // Change the signature without renaming
    public abstract bool Bar(string foo, string baz); 
    public abstract bool Bar(T foo);
}

是的,有一種方法可以避免更改方法名稱。 使用顯式接口實現(請參閱https://msdn.microsoft.com/zh-cn/library/aa288461(v=vs.71).aspx ),如下所示:

public abstract class AFoo<T> : IFoo
{
    // Change the signature without renaming
    abstract bool IFoo.Bar(string foo); 
    public abstract bool Bar(T foo);
}

AFoo將用作:

AFoo<String> af = new Implementation();
//Call generic method
Console.Writeline(af.Bar("Hello world!"));
//Call interface method
Console.Writeline(((IFoo)af).Bar("Hello world!"));

暫無
暫無

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

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