2011-10-16 26 views
3

假設我們有一個類型的人的特定對象,並希望其Name屬性中存儲到本地變量,同時避免可能出現的異常應該對象爲空,我們可以這樣做:三元運算符的例外?其他選擇?

string personName = null; 

if (person != null) 
{ 
    personName = person.Name; 
} 

但是,不必申報if語句範圍之外的變量並將其初始化爲默認值有點麻煩。相反,我們可以使用條件三元運算符寫這樣的:使用try-catch語句打交道時

string personName = person != null ? person.Name : null; 

這同樣的問題也存在。假設我們正在嘗試查找TcpClient的遠程地址。我們可以做這樣的事情:

string remoteAddress = null; 

try 
{ 
    remoteAddress = tcpClient.Client.RemoteEndPoint.ToString(); 
} 
catch (SocketException e) 
{ 
    Console.WriteLine(e.Message); 

    return; 
} 

不過,據我所知,沒有用於簡化這樣的事情定義操作,我想有很好的理由,考慮到可能的複雜性。我想知道,是否有辦法讓這種事情更簡潔?也許一個涉及monads的解決方案會起作用,或者這個代碼應該保持原樣。

回答

2

我個人的猜測是,這樣的操作符不適用於例外情況,因爲它可能會導致錯誤的編碼習慣。回想一下以下最佳實踐指南:

  1. 代碼不應該失敗默默
  2. 例外應該只在特殊情況下被拋出。

由於這幾點,你不應該需要異常處理非常頻繁(方法如TryParse幫助了很多在這裏),除了應用程序的UI頂級水平,在那裏你捕獲並記錄一切。

在你的例子中,如果TCP連接中斷,算法通常無法繼續,所以爲什麼不讓socket異常冒泡到UI層,它被捕獲並向用戶顯示一條有用的消息( 「連接丟失,請檢查您的互聯網連接。{異常詳細信息}」),而不是隻是返回並悄悄地將某些內容記錄到控制檯,讓用戶想知道爲什麼他的操作沒有完成?

+2

類似於TCP連接的情況代表了一種情況,通常適合於拋出可能被捕獲和處理的異常,因爲失敗的代碼可能在塊或方法內,並且處理異常的代碼在它之外。使用異常比「if(!TryReadOneByte(ref commandLength))break; if(!TryReadNBytes(commandLength,dat))break;等等。連接失敗應該中止當前的操作,但可能會非常合理地導致一次或多次重試(可能在不同的地址),然後冒泡到呼叫者。 – supercat

0

有一個我曾經成功使用過的Null Object Pattern的概念。也許這對你也有幫助。引用:

在面向對象的計算機編程中,空對象是具有已定義中性(「null」)行爲的對象 。

換句話說,而不是返回null返回一個定義良好的對象,充當「空對象」,從而訪問它不會拋出異常。

另外,see this Google search的更多示例。

2

從這裏:http://devtalk.net/csharp/chained-null-checks-and-the-maybe-monad/

public static TResult With<TInput, TResult>(this TInput o, 
              Func<TInput, TResult> evaluator) 
    where TResult : class where TInput : class 
{ 
    if (o == null) return null; 
    return evaluator(o); 
} 

上述方法可以連接到任何類型的(因爲TInput有效對象)。作爲參數,該方法使用定義鏈中下一個值的函數。如果我們傳遞null,則返回null。讓我們使用這種方法改寫我們的第一個例子:

string postCode = this.With(x => person) 
         .With(x => x.Address) 
         .With(x => x.PostCode); 

這對於建立「正常」之類的對象:

var person = new { Address = new { PostCode = "12345" } }; 

但可以有personAddressnull。我會在同一頁面中添加一個Result擴展方法,如果「主」值爲null,則返回默認值。

this頁面(這是指向我的那個頁面)它在一個人的願望清單中的第一個地方,他稱之爲Null Safe Dereferencing