2015-04-15 25 views
1

我想寫一個擴展方法,它將一個值與另外兩個值進行比較,並確定該值是否在另外兩個值之內。這適用於此目的單通用的可比較和可空約束

public static bool IsWithin<T>(this T value, T min, T max) where T : IComparable<T> 
{ 
    return (bool)(value.CompareTo(min) > 0 && value.CompareTo(max) < 0); 
} 

我還想擴展此方法,以在Nullable<T>上工作。如果值爲空,我希望邊界條件被忽略。我曾嘗試在T上添加額外的約束,但這不被支持。下面的代碼不能編譯,但是我想實現。

public static bool IsWithinInclusive<T>(this T value, Nullable<T> min, Nullable<T> max) where T : IComparable<T> 
{ 
    return (bool)(
     (min.HasValue ? value.CompareTo(min) >= 0 : true) && 
     (max.HasValue ? value.CompareTo(max) <= 0 : true)); 
} 

是否可以編寫一個單獨的方法來實現這個目標?

+1

你不需要投給'布爾',你可以代替'一個? b:true' with'a && b' – SLaks

+1

當'min'爲null時,a && b'爲false,我希望它是真的。我錯過了什麼? – djv

+1

然後你想'!a || B'。 – SLaks

回答

4

需要約束T是一個struct匹配definition of Nullable<T>

public static bool IsWithinInclusive<T>(this T value, Nullable<T> min, Nullable<T> max) where T : struct, IComparable<T> 
{ 
    return 
     (min.HasValue ? value.CompareTo(min.Value) >= 0 : true) && 
     (max.HasValue ? value.CompareTo(max.Value) <= 0 : true); 
} 

你還需要使用.ValueNullable<T>得到T

2

當SLak回答時,原因Nullable<T>(或只是T?)不被接受是因爲它要求T是一個非空值類型。您不能使用涵蓋值類型和引用類型的單一方法:您想要支持的值類型不能代表null,並且引用類型不能支持T?,因此您無法避免使用兩種單獨的方法。

但是,您可以使用完全相同的函數體兩次,使其顯然對讀者的是,兩個重載做同樣的事情:

public static bool IsBetween<T>(this T value, T min, T max) where T : IComparable<T> 
{ 
    return (min == null || value.CompareTo((T)min) >= 0) 
     && (max == null || value.CompareTo((T)max) <= 0); 
} 

public static bool IsBetween<T>(this T value, T? min, T? max) where T : struct, IComparable<T> 
{ 
    return (min == null || value.CompareTo((T)min) >= 0) 
     && (max == null || value.CompareTo((T)max) <= 0); 
} 
+0

好的解釋,我想知道我是否需要兩種方法。你有我想要的邏輯。謝謝。 – djv