簡體   English   中英

具有通用接口和流暢方法的 C# 繼承

[英]C# Inheritance with generic interfaces and fluent methods

我試圖弄清楚如何構建一個通用的接口結構以使用流暢的表示法。

我正在嘗試使用如下結構:

public interface IGeneric<out T>
    where T : IGeneric<T>
{
    T Foo1();
    T Foo2();
    T Foo3();
}

public interface ISpecific_1 : IGeneric<ISpecific_1>
{ }

public interface ISpecific_2 : IGeneric<ISpecific_2>
{
    ISpecific_2 Bar1();
    ISpecific_2 Bar2();
    ISpecific_2 Bar3();
}

public abstract class GenericImpl<T> : IGeneric<T>
    where T : IGeneric<T>
{
    public T Foo1()
    {
        //Do things
        return (T)(object)this;
    }

    public T Foo2()
    {
        //Do things
        return (T)(object)this;
    }

    public T Foo3()
    {
        //Do things
        return (T)(object)this;
    }
}

public class SpecificImpl1 : GenericImpl<ISpecific_1>, ISpecific_1
{

}

public class SpecificImpl2 : GenericImpl<ISpecific_2>, ISpecific_2
{
    public ISpecific_2 Bar1()
    {
        //Do things
        return this;
    }

    public ISpecific_2 Bar2()
    {
        //Do things
        return this;
    }

    public ISpecific_2 Bar3()
    {
        //Do things
        return this;
    }
}

IGeneric 只接受它自己的實現作為 T,以確保 Foo1()、Foo2() 和 Foo3() 將返回正確的類型以進行流利的表示法。

GenericImpl 是抽象的(不是強制性的,但我想讓它們使用特定的類)並實現 IGeneric。

ISpecific_1 使用自己的類型實現 IGeneric(這意味着 Generic 類中的 Foos 方法將返回 ISpecific_1)。

Specific_1 實現 ISpecific_1 並擴展 GenericImpl<ISpecific_1>。

ISpecific_2 和 Specific_2 相同,除了一些 Bars 額外方法。

這似乎有效,因為我可以這樣做:

ISpecific_1 spec1 = new Specific_1();
spec1.Foo1().Foo2().Foo3(); //Everyone returns ISpecific_1 that extends the Generic class with the Foos

ISpecific_2 spec2 = new Specific_2();
spec2.Bar1().Foo1().Bar2().Foo2().Bar3().Foo3(); //Everyone returns ISpecific_2 with the Bars. Also the Generic Foos methods are available.

雖然我不能這樣做:

ISpecific_1 spec1 = new Specific_1();
spec1.Bar1().Bar2().Bar3(); //ISpecific_1 nor IGeneric don't declare Bars methods

現在問題是:

第一個:在 Foos 方法中,我必須使用手動轉換返回值

return (T)(object)this;

我也可以讓 T : class 和 use

return this as T;

它們安全還是我錯過了演員失敗的情況?

第二個:有沒有更好的方法來做到這一點?

先感謝您

最后我找不到任何真正干凈的解決方案:我不得不犧牲一些結構。

我把幾乎所有的屬性都公開了(這對我來說不是問題); 這使我能夠將所有方法作為通用擴展方法而不是類方法進行管理,並且它們仍然可以對公共屬性進行操作。

暫無
暫無

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

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