簡體   English   中英

c#中可抽象類的非可空方法的可空實現

[英]nullable implemention of non-nullable methods of an abstract class in c#

我有三節課。 一個名為A的接口,以及實現A的B和C.另外B有一個C的實例.A的方法不能為空。 但是,C可能會不時返回null。 B類檢查C實例的方法,如果C的返回值為null,它將返回自身值(來自B的值)。

public abstract class A
{
bool abstract method1();
bool abstract method2();
}

public class B:A
{
public C c;
override bool method1()
{
//if c.method1 is not null return c.method1() otherwise do some other functionality
}
}

public class C:A
{
?
}

由於某些性能問題,我不想拋出異常。 我怎樣才能實現C類,因為我無法將override類的類型更改為nullable?

您是否可以強制您的B和C類實現一個接口,該接口定義調用是否安全以及如果不安全該怎么辦?

public abstract class A
{
    bool abstract method1();
    bool abstract method2();
}

public interface IFallbackIfNotSafe {
    public bool IsSafe();
    public bool Fallback();
}

public class B : A, IFallbackIfNotSafe
{
    public C c {get;set;}

    bool override method1()
    {
        return c.IsSafe() ? c.method1() : Fallback();
    }

    bool override method2()
    {
        //...
    }

    public bool Fallback(){
        //...
    }

    public bool IsSafe(){
        // make sure this B instance is safe
    }
}

public class C : A, IFallbackIfNotSafe
{
    bool override method1()
    {
        //...
    }

    bool override method2()
    {
        //...
    }

    public bool IsSafe(){
        // make sure this C instance is safe
    }

    public bool Fallback(){
        //...
    }
}

我只是同意其他評論員:你已經定義了一個接口,它定義了你可以從實現這個接口的類中得到的結果。 不想要更改hevaviour,這意味着您要么調整接口以滿足新要求,要么在C類需要違反接口定義時拋出異常(null不在def - >違規內)。

在我們確實被拋出之前,我所知道的例外沒有性能損失。 因此,您無法猜測在某些情況下是否更好地處理異常或在所有情況下檢查空值。

最好不要只有C實現A並且只包含獲取相同數據的方法並讓它們返回bool? 聽起來B仍然可以滿足A所規定的合同。

如果那不是一個選項,我只會拋出異常並在B捕獲它。

根據所述的嚴格要求,我設法提出了一種愚蠢的解決方案,但是很好 - 這是......

void Main()
{
    var a = new AProxy(new C(), new B());
    for (int i = 0; i < 15; i++)
    {
        a.method1();
        a.method2();
    }
}
public abstract class A
{
    public abstract bool method1();
    public abstract bool method2();
}
public class AProxy : A
{
    readonly A primary;
    readonly A secondary;
    public AProxy(A primary, A secondary)
    {
        this.primary = primary;
        this.secondary = secondary; 
        if(primary is IReturnsNulls)
            ((IReturnsNulls)primary).LastResultNull += (s, e) =>
                useSecondary = true;
    }
    private bool useSecondary;
    private bool UseSecondary
    {
        get 
        {
            if(useSecondary == true)
            {
                useSecondary = false;
                return true;
            }
            return useSecondary;
        }
    }
    public override bool method1()
    {
        var result = primary.method1();
        return UseSecondary ? secondary.method1() : result;
    }
    public override bool method2()
    {
        var result = primary.method2();
        return UseSecondary ? secondary.method2() : result;
    }
}
public class B : A
{
    public override bool method1()
    {
        Console.WriteLine ("B, method1 (secondary)");
        return true;
    }
    public override bool method2()
    {
        Console.WriteLine ("B, method2 (secondary)");
        return true;
    }
}
public interface IReturnsNulls
{
    event EventHandler LastResultNull;
}
public class C : A, IReturnsNulls
{   
    static Random random = new Random();
    public override bool method1()
    {
        Console.WriteLine ("C, method1");
        var result = (random.Next(5) == 1) ? (bool?)null : true;
        if(result == null && LastResultNull != null)
            LastResultNull(this, EventArgs.Empty);
        return result ?? false;
    }
    public override bool method2()
    {
        Console.WriteLine ("C, method2");
        var result = (random.Next(5) == 1) ? (bool?)null : true;
        if(result == null && LastResultNull != null)
            LastResultNull(this, EventArgs.Empty);
        return result ?? false;
    }
    public event EventHandler LastResultNull;
}

輸出

C, method1
B, method1 (secondary)
C, method2
C, method1
C, method2
B, method2 (secondary)
C, method1
C, method2
C, method1
C, method2
C, method1
C, method2
C, method1
C, method2
C, method1
C, method2
C, method1
C, method2
C, method1
B, method1 (secondary)
C, method2
C, method1
C, method2
C, method1
C, method2
B, method2 (secondary)
C, method1
C, method2
C, method1
C, method2
B, method2 (secondary)
C, method1
C, method2
C, method1
C, method2

暫無
暫無

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

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