因此,我沒有找到任何優雅的解決方案,無論是使用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;
}
只是非常,這種結構的葉性質將永遠是原語,或在這種情況下,我給適當的治療可空基元。這是我必須爲每個我需要的財產做的「邏輯」,有時我必須使用其中的一些。另外,真正的結構是相當大的,所以我需要做的驗證數量也會對每個必要的屬性更大。現在
,我想出了一些想法,他們沒有,我認爲是理想的:
- 創建方法收集的屬性,它會抽象的任何必要的核查,或獲得默認值的邏輯。缺點是在我看來,它會有一些重複的代碼,因爲驗證和默認值對於某些字段組是相似的。
- 創建一個通用方法,它在其中接收對象,並創建一個訪問所需字段的lamba函數。此方法會嘗試執行該函數並返回它的結果,如果發生NullReferenceException,它將返回一個默認值。這一點的亮點在於它是通用的,我只需要通過lambda來訪問屬性,並且該方法可以處理任何問題。它的缺點是,我正在使用try - > catch來控制邏輯,這不是它的目的,代碼可能會讓其他程序員感到困惑,最終會對其進行維護。
- 空對象模式,這將是最優雅的解決方案,我猜。如果是正常情況,它將具有所有優點。但是這個結構提供了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,但它是好遠了,我發現,到目前爲止,因爲我不熟悉擴展方法的任何解決方案,我真的學到了很多東西。
再次感謝。
這裏討論http://stackoverflow.com/q/2080647/2300730與你的問題有關,從那裏的一些技巧可能有幫助 – jure 2013-05-13 14:48:22
謝謝,那篇文章討論了設計的一些方面,這很有趣,我也發現我不熟悉的「德米特定律」 – JeanK 2013-12-20 17:16:16