2008-09-29 74 views
30

如果我想要一個只接受重載操作符的類型的泛型方法(例如減法運算符),該怎麼辦?我嘗試使用一個接口作爲約束,但接口不能有運算符重載。.NET泛型中重載操作符約束的解決方案

達到此目的的最佳方法是什麼?

+1

你有一個例子,你正在嘗試使用這個?我想不出任何有用的東西? – 2008-09-29 05:40:49

+0

通用的「總和」方法將是一個簡單的例子。 T總和(IEnumerable sequence); //其中T有'+'運算符 – blackwing 2008-09-29 08:11:25

+0

[定義實現+運算符的泛型]的可能重複(http://stackoverflow.com/questions/3598341/define-a-generic-that-implements-the-operator) – Timwi 2010-09-03 13:11:09

回答

37

沒有直接的答案;運算符是靜態的,並且不能用約束條件來表示 - 而且現有的優先級沒有實現任何特定的接口(與IComparable [<T>]相比,它可以用來模擬大於/小於)。

但是;如果你只是希望它的工作,然後在.NET 3.5也有一些選項...

我已經把圖書館here,允許使用泛型運營效率和簡單的訪問 - 如:

T result = Operator.Add(first, second); // implicit <T>; here 

它可以被下載爲的MiscUtil

另外部分,在C#4.0,這通過0​​成爲可能:

static T Add<T>(T x, T y) { 
    dynamic dx = x, dy = y; 
    return dx + dy; 
} 

我也曾經(在某個時候)有一個.NET 2.0版本,但是這個版本的測試很少。另一種選擇是創建這樣的接口

interface ICalc<T> 
{ 
    T Add(T,T)() 
    T Subtract(T,T)() 
} 

等,但你需要通過所有的方法,這就會變得混亂傳遞一個ICalc<T>;

5

我發現IL實際上可以很好地處理這個問題。防爆。

ldarg.0 
ldarg.1 
add 
ret 

在一個通用的方法的經編譯的代碼將只要指定一個基本類型細運行。有可能擴展它以在非基元類型上調用操作符函數。

請參閱here

-1

有一段代碼從國際上被盜,我用了很多。它使用IL基本算術運算符查找或構建。這些都是在一個Operation<T>泛型類中完成的,你所要做的就是將所需的操作分配給一個委託。像add = Operation<double>.Add

它這樣使用:糊箱的

public struct MyPoint 
{ 
    public readonly double x, y; 
    public MyPoint(double x, double y) { this.x=x; this.y=y; } 
    // User types must have defined operators 
    public static MyPoint operator+(MyPoint a, MyPoint b) 
    { 
     return new MyPoint(a.x+b.x, a.y+b.y); 
    } 
} 
class Program 
{ 
    // Sample generic method using Operation<T> 
    public static T DoubleIt<T>(T a) 
    { 
     Func<T, T, T> add=Operation<T>.Add; 
     return add(a, a); 
    } 

    // Example of using generic math 
    static void Main(string[] args) 
    { 
     var x=DoubleIt(1);    //add integers, x=2 
     var y=DoubleIt(Math.PI);  //add doubles, y=6.2831853071795862 
     MyPoint P=new MyPoint(x, y); 
     var Q=DoubleIt(P);    //add user types, Q=(4.0,12.566370614359172) 

     var s=DoubleIt("ABC");   //concatenate strings, s="ABCABC" 
    } 
} 

Operation<T>的源代碼提供:http://pastebin.com/nuqdeY8z

下面歸屬:

/* Copyright (C) 2007 The Trustees of Indiana University 
* 
* Use, modification and distribution is subject to the Boost Software 
* License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 
* http://www.boost.org/LICENSE_1_0.txt) 
* 
* Authors: Douglas Gregor 
*   Andrew Lumsdaine 
*   
* Url:  http://www.osl.iu.edu/research/mpi.net/svn/ 
* 
* This file provides the "Operations" class, which contains common 
* reduction operations such as addition and multiplication for any 
* type. 
* 
* This code was heavily influenced by Keith Farmer's 
* Operator Overloading with Generics 
* at http://www.codeproject.com/csharp/genericoperators.asp 
* 
* All MPI related code removed by ja72. 
*/