2011-08-11 25 views
3

我想清理一個大的處理程序的方法,顯示或不在視圖上的標籤。避免空引用使用C#的可能性

實際的結構是一樣的東西:

if (Moo.Foo != null) { 
    Show(TrType, LabelType, Moo.Foo.DangerousNullRef + " - " + Moo.Foo.AnotherPossibleNullRef); 
} 
else { 
    DontShowField(TrType); 
} 

我像派參與到做無聊的東西的方法的所有組件在想,但是:

ShowHandlingNull(Moo.Foo != null, TrType, LabelType, Moo.Foo.DangerousNullRef + " - " + Moo.Foo.AnotherPossibleNullRef); 

會造成空如果Moo.Foo爲null,則爲參考。我可以委託或採取某些行動,並在我的大方法中只放一行?

+0

如果'Moo.Foo'實際上是null,那麼期望的行爲是什麼? – vcsjones

+0

@vcsjones行爲是調用else語句:'DontShowField(TrType)' – Custodio

回答

1

有已經使用Func鍵處理這似乎對我來說,最好的解決方案的想法,我只是做了你的意圖一些假設,並假定你正試圖獲得這個標籤文本,所以我寫了它。

private void YourFunction 
    { 
     Type TrType = this.GetType(); 
     MooClass Moo = new MooClass(); 
     LabelTypeEnum LabelType = LabelTypeEnum.something; 
     ShowIf(Moo, TrType, LabelType, new Object[] { Moo.Foo, Moo.Foo2, Moo.Foo3 }, a => a.Foo.DangerousNullRef + " - " + a.Foo.AnotherPossibleNullRef); 

    } 


    void ShowIf(MooClass Moo, Type t, LabelTypeEnum LabelType, IEnumerable<object> PreCheckNullsValues, Func<MooClass, string> mc) 
    { 
     if (PreCheckNullsValues.Any(a => a == null)) 
      Show(t, LabelType, mc(Moo)); 
     else 
      DontShowField(t); 
    } 

這裏有一個假設骨架您的支持代碼:

enum LabelTypeEnum 
    { 
     something 
    } 

    class MooClass 
    { 
     public FooClass Foo { get; set; } 
    } 

    class FooClass 
    { 
     public object DangerousNullRef { get; set; } 
     public object AnotherPossibleNullRef { get; set; } 
    } 

    private void Show(Type TrType, LabelTypeEnum LabelType, string p) { } 

    private void DontShowField(Type TrType) { } 

然後,您可以用行動來安全地訪問您的屬性。

+0

這是一個很好的解決方案!但我有Foo2,Foo3 ... Foo15屬性。如何動態地執行if子句if(Moo。「FooN」!= null)' – Custodio

+0

@Custódio您是否試圖檢查該類上的任何屬性是否爲空,或者某些屬性的某個隨機子集爲空? – deepee1

+0

deepee1更好的答案是隨機的。我有一個很大的Moo類,我也在重構他,但是現在我有很多屬性需要驗證是否爲null。 – Custodio

1

我不認爲這是一個改進,但它可以通過lambda的延遲執行來完成。

ShowHandlingNull(Moo.Foo, TrType, LabelType, f => f.DangerousNullRef, f => f.AnotherPossibleNullRef); 

void ShowHandlingNull(Foo foo, object trType, objectLablelType, Func<Foo, object> dangerousNullRefGetter, Funct<Foo, object> anotherDangerousGetter) 
{ 
    if (foo == null) { 
     DontShowField(trType); 
     return; 
    } 
    Show(TrType, LabelType, dangerousNullRefGetter(foo) + " - " + anotherDangerousGetter(foo)); 
} 

但我認爲您的原始if空檢查更容易理解和維護。

+0

如果Moo爲null,則會中斷 – sternr

+1

@sternr操作系統的帖子顯示他目前正在執行該操作 – Manatherin

+0

糟糕,您是對的我沒有注意到。 .. – sternr

0

你可以自己寫一些像Strings「+」一樣的方法,並檢查null-References(並將它作爲字符串的擴展方法添加),但我認爲這樣做會過度。 只需用「Moo」(無論類型可能)參數更改/重載show-method並在那裏檢查。

0

爲什麼不嘗試使用它接受空

public static string ShowHandlingNull(this Foo foo, TrType trType, LabelType labelType) 
{ 
    if (foo == null) 
    { 
     return string.Empty; 
    } 
    return ...... 
} 

var result = Moo.Foo.ShowHandlingNull(trType, labelType); 
+0

這是一個解決方案,但在我的方法中,Moo包含很多Foo屬性。所以我需要創建n *個屬性擴展。 :/ 我很快計算在這裏,它的n約爲15 – Custodio

0

用小擴展方法擴展方法:

public static class OrEmpty<T>(this T instance) where T : class, new() 
{ 
    return instance ?? new T(); 
} 

例子:

Show(TrType, LabelType, Moo.Foo.OrEmpty().DangerousNullRef + " - " + Moo.Foo.OrEmpty().AnotherPossibleNullRef); 

注意,它會創建一個每次通話新對象。您可以稍微提高一點以避免創建大量對象。

1

您可以按照Null Object pattern的指導原則進行操作。

例如,Moo.Foo可能成爲一個接口,實際的類應該成爲所述接口的實現。然後創建一個MooFooNull類,它處理Foo爲null的情況,即DontShowField方法。

// On Moo.Foo initialization, if the condition for creating of RealMooFoo are not met. 
Moo.Foo = new MooFooNull(this); 

// later on ... 
Moo.Foo.Show(TrType, LabelType, Moo.Foo.DangerousNullRef + " - " + Moo.Foo.AnotherPossibleNullRef); 

其中MooFooNull的Show方法是:

void Show(TheClass theClass, object trType, ...) { 
    theClass.DontShowField(trType); 
} 
+0

這是一個解決方案,但在我的方法中,Moo包含很多Foo屬性。所以我需要創建n *個屬性擴展。 :/我很快計算在這裏,其n約爲15 – Custodio

+0

你可以創建一個DTO與所需的數據...好的,保持如果;-) – Simone