簡體   English   中英

是否有抽象方法的顯式接口聲明?

[英]is there an explicit interface declaration for abstract methods?

我有一個(很簡單的)問題,似乎我不知道如何去做。 我會很感激一些幫助。

我有兩個類是這樣的:

public class FileParameters { ... }

public abstract class File {
    ...
    public abstract FileParameters Params { get; }
}

從兩個類中,我都有一個派生的特殊版本:

public class SpecialFileParameters { ... }

public abstract class SpecialFile {
    ...
    private SpecialFileParameters params;
    public override FileParameters Params { get { return params; } }
}

當我想使用 SpecialFileParameters 時,我必須先轉換它們,例如:

((SpecialFileParameters)SpecialFileObject.Parameters).DoSomething();

這是非常令人討厭的。 我想要的語法與接口基本相同

public abstract class SpecialFile {
    ...
    private SpecialFileParameters params;
    private override FileParameters File.Params { get { return params; } }
    public new SpecialFileParameters Params { get { return params; } }
}

但是像這樣我得到一個編譯器錯誤:顯式接口聲明中的“文件”不是一個接口。 有沒有其他方法可以做到這一點?

一些進一步的信息:

  • 我不能改變基類,只能改變我的特殊類
  • 我實際上需要 2 個特殊的派生類,一個是用 C# 編寫的,另一個是用 C++/CLI 編寫的。 如果 C# 和 C++ CLI 之間的“技巧”使其工作不同,請告訴我。

感謝您的幫助(我猜還有耐心^^),

它在 C++/CLI 中有些不同,顯式覆蓋的示例:

public ref struct BaseClass abstract
{
    virtual int Func(int) abstract;
};

public ref struct DerivedClass : BaseClass
{
    virtual int BaseFunc(int x) = BaseClass::Func { return x + 2; }
    virtual int Func(int y) new { return y / 2; }
};

int main(array<System::String ^> ^args)
{
    DerivedClass^ d = gcnew DerivedClass();
    BaseClass^ b = d;
    System::Console::WriteLine("4 ->  Base   -> " + b->Func(4));
    System::Console::WriteLine("4 -> Derived -> " + d->Func(4));

    return 0;
}

Marc 已經展示了您需要為 C# 做什么:使用額外的繼承層。

不,C# 中沒有用於標記顯式抽象覆蓋方法的語法(與具有相同簽名的另一個方法不同),並且由於您不能在同一級別聲明兩個匹配的簽名,因此您不能完全按照自己的意願行事.

由於您已經排除了更改基類的可能性,因此我唯一的建議是添加一個人為的額外級別:

public abstract class File {
    public abstract FileParameters Params { get; }
}
public abstract class FileIntermediate : File
{
    public override FileParameters Params {get { return ParamsImpl; }}
    protected abstract FileParameters ParamsImpl { get; }
}
public class SpecialFile : FileIntermediate
{
    public new SpecialFileParameters Params { get { return null; } }// TODO 
    protected override FileParameters ParamsImpl {get { return Params; }}
}

您可以使用泛型來解決這個問題:

    public class FileParameters   {    }

    public class SpecialFileParameters : FileParameters{}

    public abstract class File<T>
        where T : FileParameters
    {
        private T _params;

        public T Params   { get { return _params;}        }
    }

    public class SpecialFileParams : FileParameters<SpecialFileParameters> { }

當您訪問參數時,您將獲得具體的“特殊”。

兩種方法(覆蓋和新方法)之間是否需要具有相同的方法名稱? 在這些情況下,我通常會創建一個具有新名稱的新方法,該方法返回派生程度更高的類型,然后讓覆蓋在其實現中調用此方法:

public override FileParameters Params { get { return SpecialParams; } }     
public SpecialFileParameters SpecialParams { get { return params; } } 

這樣,當你有一個 SpecialFile 對象時,你就不需要強制轉換了。 如果這不起作用,也許您可​​以解釋更多為什么您需要方法的名稱與您的情況相同。

暫無
暫無

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

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