java限制数字_是否存在将我的通用方法限制为数字类型的约束?
誰能告訴我泛型是否可以將泛型類型參數(shù)T限制為:
Int16
Int32
Int64
UInt16
UInt32
UInt64
我知道where關鍵字,但是找不到僅適用于這些類型的接口,
就像是:
static bool IntegerFunction(T value) where T : INumeric
#1樓
這個問題有點像是一個常見問題,所以我將其發(fā)布為Wiki(因為我之前發(fā)布過類似的文章,但這是一個較舊的問題); 無論如何...
您正在使用什么版本的.NET? 如果您使用的是.NET 3.5,那么我在MiscUtil (免費等)中有一個通用的運算符實現(xiàn) 。
它具有T Add(T x, T y) ,以及用于不同類型(如DateTime + TimeSpan )的其他算術變體。
此外,這適用于所有內(nèi)置,提升和定制的運算符,并緩存代表以提高性能。
為什么這是棘手的一些其他背景在這里 。
您可能還想知道dynamic (4.0)排序也間接解決了此問題-即
dynamic x = ..., y = ...
dynamic result = x + y; // does what you expect
#2樓
.NET數(shù)字基元類型不共享任何允許它們用于計算的通用接口。 可以定義自己的接口(例如ISignedWholeNumber ),該接口將執(zhí)行此類操作,定義包含單個Int16 , Int32等的結構并實現(xiàn)這些接口,然后具有接受約束到ISignedWholeNumber泛型類型的方法,但具有將數(shù)值轉(zhuǎn)換為您的結構類型可能會很麻煩。
一種替代方法是使用靜態(tài)屬性bool Available {get;};定義靜態(tài)類Int64Converter bool Available {get;}; 以及Int64 GetInt64(T value) , T FromInt64(Int64 value) , bool TryStoreInt64(Int64 value, ref T dest)靜態(tài)委托。 該類的構造函數(shù)可以使用硬編碼來加載已知類型的委托,并可以使用Reflection來測試T類型是否使用正確的名稱和簽名來實現(xiàn)方法(如果它像包含Int64并表示數(shù)字的結構那樣,但具有自定義的ToString()方法)。 這種方法將失去與編譯時類型檢查相關的優(yōu)勢,但是仍然可以避免裝箱操作,并且每種類型僅需“檢查”一次。 之后,與該類型關聯(lián)的操作將被委托分派替換。
#3樓
我創(chuàng)建了一些庫功能來解決這些問題:
代替:
public T DifficultCalculation(T a, T b)
{
T result = a * b + a; // <== WILL NOT COMPILE!
return result;
}
Console.WriteLine(DifficultCalculation(2, 3)); // Should result in 8.
您可以這樣寫:
public T DifficultCalculation(Number a, Number b)
{
Number result = a * b + a;
return (T)result;
}
Console.WriteLine(DifficultCalculation(2, 3)); // Results in 8.
#4樓
我會使用一種通用的,您可以處理外部性...
///
/// Generic object copy of the same type
///
/// The type of object to copy
/// The source object to copy
public T CopyObject(T ObjectSource)
{
T NewObject = System.Activator.CreateInstance();
foreach (PropertyInfo p in ObjectSource.GetType().GetProperties())
NewObject.GetType().GetProperty(p.Name).SetValue(NewObject, p.GetValue(ObjectSource, null), null);
return NewObject;
}
#5樓
考慮到這個問題的普遍性以及這種功能背后的興趣,我很驚訝地看到還沒有涉及T4的答案。
在這個示例代碼中,我將演示一個非常簡單的示例,說明如何使用功能強大的模板引擎來完成編譯器在泛型背后的工作。
您無需花錢,也不必犧牲編譯時的確定性,您只需為所需的每種類型生成所需的函數(shù),然后相應地使用它即可(在編譯時!)。
為此:
創(chuàng)建一個名為GenericNumberMethodTemplate.tt的新文本模板文件。
刪除自動生成的代碼(您將保留其中的大部分,但不需要其中的一部分)。
添加以下代碼段:
typeof(Int16), typeof(Int32), typeof(Int64),
typeof(UInt16), typeof(UInt32), typeof(UInt64)
};
#>
using System;
public static class MaxMath {
#>
public static Max ( val1, val2) {
return val1 > val2 ? val1 : val2;
}
} #>
}
而已。 現(xiàn)在完成了。
保存此文件將自動將其編譯為該源文件:
using System;
public static class MaxMath {
public static Int16 Max (Int16 val1, Int16 val2) {
return val1 > val2 ? val1 : val2;
}
public static Int32 Max (Int32 val1, Int32 val2) {
return val1 > val2 ? val1 : val2;
}
public static Int64 Max (Int64 val1, Int64 val2) {
return val1 > val2 ? val1 : val2;
}
public static UInt16 Max (UInt16 val1, UInt16 val2) {
return val1 > val2 ? val1 : val2;
}
public static UInt32 Max (UInt32 val1, UInt32 val2) {
return val1 > val2 ? val1 : val2;
}
public static UInt64 Max (UInt64 val1, UInt64 val2) {
return val1 > val2 ? val1 : val2;
}
}
在您的main方法中,您可以驗證自己具有編譯時確定性:
namespace TTTTTest
{
class Program
{
static void Main(string[] args)
{
long val1 = 5L;
long val2 = 10L;
Console.WriteLine(MaxMath.Max(val1, val2));
Console.Read();
}
}
}
我先說一句話??:不,這不違反DRY原則。 DRY原則是為了防止人們在多個地方復制代碼,這將導致應用程序變得難以維護。
這里根本不是這種情況:如果您想進行更改,則只需更改模板(您這一代人的一個單一來源!)就可以完成。
為了將其與您自己的自定義定義一起使用,請在生成的代碼中添加一個名稱空間聲明(確保它與定義自己的實現(xiàn)的聲明相同),并將該類標記為partial 。 然后,將這些行添加到模板文件中,以便將其包括在最終的編譯中:
老實說:這很酷。
總結
以上是生活随笔為你收集整理的java限制数字_是否存在将我的通用方法限制为数字类型的约束?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 自然风干的果干是脆的吗?
- 下一篇: 浅析后疫情时代西式快餐的经营模式?