![](/img/trans.png)
[英]Why can't I use 'as' with generic type parameter that is constrained to be an interface?
[英]How can I implement a method with a generic parameter (constrained to an integer type) with a cast?
我基本上希望它可以編譯:
T ISqrtN<T>(T N) => (T)Math.Sqrt((double)N);
類型T
將是System.UInt32
, System.UInt64
(但可能更多)。
還是我必須分別實現每種ISqrtN
類型(重載)?
C#不支持通用數字。 沒有通用的數字基類型,也沒有接口聲明基本的數字運算。 最簡單的方法是避免用戶超載
uint ISqrtN(uint N) => (uint)Math.Sqrt((double)N);
ulong ISqrtN(ulong N) => (ulong)Math.Sqrt((double)N);
然后,IntelliSense將顯式顯示允許的參數類型。 例如,這就是Math
類對Abs
或Max
的作用。
重載解析是在編譯時執行的,即使對於通用方法也是如此。 首選的解決方案是根本不使用通用方法,因為您不能將T
限制為可以防止人們調用ISqrtN<DateTime>
等的類型。
維護通用方法簽名的解決方法是使用dynamic
運行時綁定:
T ISqrtN<T>(T N) => (T)Math.Sqrt((dynamic)N);
或手動類型檢查並轉換為特定的受支持類型:
T ISqrtN<T>(T N)
{
if (typeof(T) == typeof(uint))
return (T)(object)(uint)Math.Sqrt((uint)(object)N);
else if (typeof(T) == typeof(ulong))
return (T)(object)(ulong)Math.Sqrt((ulong)(object)N);
else
throw new ArgumentException();
}
要求進行中間(object)
強制轉換,因為C#不允許從T
直接轉換為uint
,但是它們在運行時不會有所作為。
您將不得不分別實現它們。 最好的辦法是對where T : struct
的值類型使用通用類型約束,但這將允許發送任何結構。 如果您確實希望對uint
和ulong
施加約束,那么我建議您將原始實現保留為私有方法,並僅創建其他2個公共方法,每個公共方法針對您要支持的類型,然后將它們稱為私有方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.