2013-05-13 57 views
2

因此,我沒有找到任何優雅的解決方案,無論是使用Google搜索還是整個計算器。我想我的手中有一個非常特殊的情況,無論如何它在這裏:c# - 當這些屬性的父項可以或不能爲空時返回空屬性的默認值

我有一個對象結構,我沒有控制權,因爲我從外部WS接收這個結構。這是一個相當大的對象,具有各種級別的字段和屬性,並且這些字段和屬性可以或不可以爲null,任何級別。你可以將這個對象看作是一個貧血模型,它沒有行爲,只是狀態。

對於這個問題的目的,我給你一個模擬我的情況的簡化示例:

Class A 
    PropB1 
    PropC11 
     PropLeaf111 
    PropC12 
     PropLeaf112 
    PropB2 
    PropC21 
     PropLeaf211 
    PropC22 
     PropLeaf221 

所以,在我的代碼,我訪問了一些這些特性,在不同層次,做一些數學計算我需要的東西。基本上對於我必須做的每種類型的計算,我必須測試我需要的每個級別的屬性,以檢查它是否爲空,在這種情況下,我將返回(十進制)0或任何其他默認值,具體取決於業務邏輯。

數學的樣品,我必須用它做:

var value = 0; 
if (objClassA.PropB1 != null && objClassA.PropB1.PropC11 != null) { 
    var leaf = objClassA.PropB1.PropC11.PropLeaf111; 
    value = leaf.HasValue ? leaf.Value : value; 
} 

只是非常,這種結構的葉性質將永遠是原語,或在這種情況下,我給適當的治療可空基元。這是我必須爲每個我需要的財產做的「邏輯」,有時我必須使用其中的一些。另外,真正的結構是相當大的,所以我需要做的驗證數量也會對每個必要的屬性更大。現在

,我想出了一些想法,他們沒有,我認爲是理想的:

  1. 創建方法收集的屬性,它會抽象的任何必要的核查,或獲得默認值的邏輯。缺點是在我看來,它會有一些重複的代碼,因爲驗證和默認值對於某些字段組是相似的。
  2. 創建一個通用方法,它在其中接收對象,並創建一個訪問所需字段的lamba函數。此方法會嘗試執行該函數並返回它的結果,如果發生NullReferenceException,它將返回一個默認值。這一點的亮點在於它是通用的,我只需要通過lambda來訪問屬性,並且該方法可以處理任何問題。它的缺點是,我正在使用try - > catch來控制邏輯,這不是它的目的,代碼可能會讓其他程序員感到困惑,最終會對其進行維護。
  3. 空對象模式,這將是最優雅的解決方案,我猜。如果是正常情況,它將具有所有優點。但是這個結構提供了Null對象的影響。爲了提供更多的背景知識,我正在研究的軟件與政府的服務相結合,我所使用的政府規範中的結構具有某些字段,其中null的含義與其他字段不同默認值如「0」。此外,這個規範會不時變化,並且這些類會重新生成,而我爲創建空對象所需做的後處理也需要維護,這對我來說似乎有點危險。

我希望我已經說清楚了。

在此先感謝。

解決方案

這是如何我解決我的問題的基礎上,接受的答案的響應。

我對C#很陌生,而且這種相關的discution確實幫助我在許多方面提出了一個優雅的解決方案。我仍然有問題,取決於代碼執行的地方,它使用.NET 2.0,但我也找到了這個問題的解決方案,我可以在其中定義擴展方法:https://stackoverflow.com/a/707160/649790

而對於解決方案本身,我發現這一個最好的: http://www.codeproject.com/Articles/109026/Chained-null-checks-and-the-Maybe-monad

我基本上可以訪問屬性這樣,只是做數學題:

objClassA.With(o => o.PropB1).With(o => PropC11).Return(o => PropLeaf111, 0); 

對於每一個我需要的屬性。它仍然是不只是:

objClassA.PropB1.PropC11.PropLeaf111 

ofcourse,但它是好遠了,我發現,到目前爲止,因爲我不熟悉擴展方法的任何解決方案,我真的學到了很多東西。

再次感謝。

+3

這裏討論http://stackoverflow.com/q/2080647/2300730與你的問題有關,從那裏的一些技巧可能有幫助 – jure 2013-05-13 14:48:22

+0

謝謝,那篇文章討論了設計的一些方面,這很有趣,我也發現我不熟悉的「德米特定律」 – JeanK 2013-12-20 17:16:16

回答

4

有一個處理這個問題的策略,涉及"Maybe" Monad

基本上它的工作原理是提供一個「流暢」的界面,其中屬性鏈被沿着鏈條某處的null打斷。

在這裏看到一個例子:http://smellegantcode.wordpress.com/2008/12/11/the-maybe-monad-in-c/

和這裏:

http://www.codeproject.com/Articles/109026/Chained-null-checks-and-the-Maybe-monad http://mikehadlow.blogspot.co.uk/2011/01/monads-in-c-5-maybe.html

它有關,但不完全一樣的,你好像有什麼需要;不過,也許它可以適應您的需求。這些概念相當重要。