2009-02-17 43 views
5

在函數式語言中,通常會有一個Maybe monad,它允許您將多個調用鏈接到一個對象上,並且如果鏈的任何部分評估爲無,則整個表達式將返回None/null,而不是您獲得的典型NullReferenceException C#通過鏈接調用,其中一個對象可以爲null。C#中有條件的去引用操作符會是一件好事嗎?

這可以通過編寫帶有一些擴展方法的Maybe<T>來實現,以允許C#中使用查詢解析的類似行爲,這在使用可選元素/屬性處理XML時非常有用,例如,

var val = from foo in doc.Elements("foo").FirstOrDefault().ToMaybe() 
      from bar in foo.Attribute("bar").ToMaybe() 
      select bar.Value; 

但這種語法有點笨重,不直觀,因爲人們習慣於處理與LINQ的序列,而不是單一的元素,它給你留下一個Maybe<T>而非T末。一個有條件的去參考運算符(例如..)是否足以用於語言?例如

var val = doc.Elements("foo").FirstOrDefault()..Attribute("bar")..Value; 

有條件去引用將擴展爲類似:

object val; 
var foo = doc.Elements("foo").FirstOrDefault(); 
if (foo != null) 
{ 
    var bar = foo.Attribute("bar"); 
    if (bar != null) 
    { 
     val = bar.Value; 
    } 
    else 
    { 
     val = null; 
    } 
} 

我可以看到,這可能會導致可怕的虐待喜歡用..處處以避免NullReferenceException,但另一方面如果使用得當,在不少情況下可能會非常方便。思考?

+0

我喜歡這個主意,很多。我強烈建議使用其他的````。也許`??。`。無論如何,與```不同的是,這不是一個常見的錯字。 – 2013-10-03 15:55:12

回答

1

在對象上鍊接多個調用使我擔心違反Law of Demeter。因此,我對這個功能是一個好主意感到懷疑,至少在解決你使用的具體問題方面是一個例子。

+0

我特別選擇了XML示例,以便展示一種情況,即在做任何實際有用的事情時,實際上不可能違反此法則,因爲XML是一個記錄良好的樹結構,我認爲這種法律不適用。 – 2009-02-17 21:26:09

+0

得墨忒耳定律的問題在於,有人將其命名爲「得墨忒耳定律」,而不是「得墨忒耳準則」,它就是這樣。有指導方針可以指導我們,但他們不應妨礙好主意。 – 2009-02-17 21:38:08

0

這是一個有趣的想法,可以用擴展方法來實現。像這樣的事情,例如(注意,只是舉例 - 我敢肯定,它可以細化):

public static IEnumerable<T> Maybe<T>(this IEnumerable<T> lhs, Func<IEnumerable<T>, T> rhs) 
{ 
    if (lhs != null) 
    { 
    return rhs(lhs); 
    } 

    return lhs; 
} 
0

我懷疑可爲空和擴展方法的組合將允許B獲得了這方面的一個顯著部分。

這會限制T值類型當然。

(TBH我寧願看到的langauge元組的支持,消除了參數,如F#一樣。)

您的代碼可以簡化,VAL設置爲空,你消除else分支。

-2

我可以看到潛在的用處,但是如果元素通常爲空,那麼除了輕微的性能影響之外,爲什麼不用一個try..catch塊代替NullReferenceException呢?