2013-03-29 76 views
1

我寫了這個簡單的實用功能:通用類型化的函數:返回一個非空值

public static T isNull<T>(T? v, T d) 
{ 
    return v == null ? d : v.Value; 
} 

的目的是爲了避免像檢查惱人的任務成員爲空,很普通的在讀LINQ記錄。問題是,它拋出這個錯誤:

The type 'T' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Nullable< T>'

的錯誤似乎合法的,反正我希望我可以做這樣的事情:的

int? myField = record.myField; 
int myValue = isNull(myField, 0); 

代替:

int? myField = record.myField; 
int myValue = myField == null ? 0 : myField.Value; 

我覺得就像我錯過了一些C#的基本知識。有沒有辦法完成我的任務?

回答

4

這就是所謂的空合併,並有一個內置的操作做到這一點:

int myValue = record.myField ?? 0 
+1

出於完整性:http://msdn.microsoft.com/en-us/library/ms173224.aspx –

+0

@LynnCrumbling謝謝,這是一個痛苦在手機上獲取引用 –

6

Generic constraints可用於泛型函數來限制允許用於某些子集的類型,這爲您如何在方法或類中使用這些類型打開了可能性。

在這種情況下,您可以對T應用一個約束,將其限制爲struct以解決您的特定編譯器錯誤。

public static T IsNull<T>(T? v, T d) where T : struct 
{ 
    return v == null ? d : v.Value; 
} 

然而,另一個回答也正確地指出,你可以選擇使用空合併運算符??在這個特別情況。

3

而其他的答案是好的,想必你想要寫你的方法,因此將與這兩個合作參考和值類型。你可以通過使用兩個重載來完成這個任務,這兩個重載都有通用約束

public static T IsNull<T>(T v, T d) where T : class 
{ 
    return v ?? d; 
} 

public static T IsNull<T>(T? v, T d) where T : struct 
{ 
    return v.HasValue ? v.Value : d; 
} 

注:調用IsNullNullable<T>以外的值類型將仍然無法編譯。例如

string myString = ... 
Console.WriteLine(IsNull(myString, "foo"))   // works 

object myObject = ... 
Console.WriteLine(IsNull(myMyObject, new object())) // works 

DateTime? myDateTime = ... 
Console.WriteLine(IsNull(myDateTme, DateTme.Now))  // works 

int? myInt1 = ... 
Console.WriteLine(IsNull(myInt1, DateTme.Now))  // works 

int myInt2 = ... 
Console.WriteLine(IsNull(myInt2, DateTme.Now))  // <-- compiler error 
相關問題