有人可以解釋爲什麼這不起作用嗎?我試圖能夠添加兩個值,無論數字類型。C#添加兩個通用值
public static T Add<T> (T number1, T number2)
{
return number1 + number2;
}
當我編譯,我得到以下錯誤:
Operator '+' cannot be applied to operands of type 'T' and 'T'
有人可以解釋爲什麼這不起作用嗎?我試圖能夠添加兩個值,無論數字類型。C#添加兩個通用值
public static T Add<T> (T number1, T number2)
{
return number1 + number2;
}
當我編譯,我得到以下錯誤:
Operator '+' cannot be applied to operands of type 'T' and 'T'
有沒有通用的約束,允許您強制執行操作符重載。您可以查看following library。另外,如果您使用的是.NET 4.0中,您可以使用關鍵字dynamic
:
public static T Add<T>(T number1, T number2)
{
dynamic a = number1;
dynamic b = number2;
return a + b;
}
顯然,這並不適用於任何編譯時安全這正是泛型都是爲了。應用編譯時安全性的唯一方法是強制執行通用約束。對於您的場景,沒有可用的限制。這只是欺騙編譯器的一個技巧。如果Add方法的調用方不傳遞與+運算符一起工作的類型,則代碼將在運行時拋出異常。
T型不是由編譯器知道,所以它不能找到任何地方定義的重載+操作...
目前可以做的最好的就是聲明你的方法,這樣的(因爲所有的數字類型轉換爲雙):
public static double Add (double number1, double number2)
{
return number1 + number2;
}
,或者如果你確定一個合適的+操作會被定義爲:
public static T Add<T>(T number1, T number2)
{
dynamic dynamic1 = number1;
dynamic dynamic2 = number2;
return dynamic1 + dynamic2;
}
更新
或兩者的組合:
public static T Add<T>(T in1, T in2)
{
var d1 = Convert.ToDouble(in1);
var d2 = Convert.ToDouble(in2);
return (T)(dynamic)(d1 + d2);
}
小數不能轉換爲雙隱式。 – kol
@kol好的一點,從我的答案隱含刪除。 –
這是我剛當我想要一個通用的方法,可以在數任意名單工作,例如一個問題:
public T Calculate<T>(IEnumerable<T> numbers);
我找到的解決方案是使用lambda表達式:
public T Calculate<T>(Func<T, T, T> add, IEnumerable<T> numbers);
哪個你最好的通過
var sum = this.Calculate((a, b) => a + b, someListOfNumbers);
很顯然,在某些情況下,你可能也只是有+的代碼,而不是lambda表達式內,但如果你需要了一般方法這個執行數學運算n個通話是最容易的事情我可以拿出那個編譯安全。
這裏給出的解決方案的工作很好,但我想我會再添一個,它使用表達式
public static T Add<T>(T a, T b)
{
// Declare the parameters
var paramA = Expression.Parameter(typeof(T), "a");
var paramB = Expression.Parameter(typeof(T), "b");
// Add the parameters together
BinaryExpression body = Expression.Add(paramA, paramB);
// Compile it
Func<T, T, T> add = Expression.Lambda<Func<T, T, T>>(body, paramA, paramB).Compile();
// Call it
return add(a, b);
}
這樣,你要創建一個Func<T, T, T>
執行加法。 詳細解釋請參見this article。
public class generic<T>
{
T result;
public generic(T eval1, T eval2)
{
dynamic a = eval1;
dynamic b = eval2;
result = a + b;
Console.WriteLine(result);
Console.ReadLine();
}
static void Main(string[] args)
{
generic<int> genobj = new generic<int>(20,30);
}
Since this is generic type without a constraint compiler has no knowledge if the types involved will have '+' overloaded hence the compiler error
These are some workarounds
public static TResult Add<T1, T2, TResult>(T1 left, T2 right, Func<T1, T2, TResult> AddMethod)
{
return AddMethod(left, right);
}
var finalLabel = Add("something", 3,(a,b) => a + b.ToString());
Below code could let you build same but evaluated at run time so not run time safe
public static T AddExpression<T>(T left, T right)
{
ParameterExpression leftOperand = Expression.Parameter(typeof(T), "left");
ParameterExpression rightOperand = Expression.Parameter(typeof(T), "right");
BinaryExpression body = Expression.Add(leftOperand, rightOperand);
Expression<Func<T, T, T>> adder = Expression.Lambda<Func<T, T, T>>(
body, leftOperand, rightOperand);
Func<T, T, T> theDelegate = adder.Compile();
return theDelegate(left, right);
}
這防止開發者編寫缺陷代碼。有幾個問題可以更好地解釋這個問題:
1>編譯器是否知道類型[No,因爲它是泛型類型]。 2>它可以接受的對象作爲參數[是的,它可以,因爲它不會知道如何處理它們 - >越野車代碼]
因爲,你想防止你的代碼是越野車, C#不允許你有'+'''和其他操作符。
解決方案: 如果需要,您可以使用「dynamic」,「var」類型並返回它們的總和。
因爲沒有人通過使用對象提供解決方案來回答。因此我正在添加我的解決方案。在這你必須將你的通用值轉換爲對象。
因此,這是工作代碼:
試試這個代碼。這是添加的通用代碼。
public static dynamic AddAllType(dynamic x, dynamic y)
{
return x + y;
}
C#編譯器做這個,所以你不寫bug的代碼。如果編譯器不知道T,它不知道如何添加T值。它也不知道T的結果類型,在這種情況下是加法。 – JonH
參數是否被強制爲「數字類型」? –