如果我想要一个通用方法,只接受已重载运算符的类型,例如减法运算符,那我该怎么做?我试过使用接口作为约束条件,但接口无法进行运算符重载。
如何最好地实现这个方法?
如果我想要一个通用方法,只接受已重载运算符的类型,例如减法运算符,那我该怎么做?我试过使用接口作为约束条件,但接口无法进行运算符重载。
如何最好地实现这个方法?
没有直接的答案;运算符是静态的,不能在约束中表达 - 现有的原语也没有实现任何特定的接口(与 IComparable[<T>] 相比,后者可以用于模拟大于/小于)。
然而,如果您只想让它工作,在 .NET 3.5 中有一些选择...
我已经组合了一个库这里,可以有效且简单地访问泛型运算符,例如:
T result = Operator.Add(first, second); // implicit <T>; here
它可以作为MiscUtil的一部分下载。
此外,在C# 4.0中,通过dynamic
也变得可能:
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>;
,这会变得混乱。
+
的这种含义... - Marc Gravell我发现IL实际上可以很好地处理这个问题。例如:
ldarg.0
ldarg.1
add
ret
只要指定了原始类型,通用方法编译后将可以正常运行。如果可能的话,可以扩展其功能以在非原始类型上调用操作函数。
请参见此处。
public class Example
{
public static T Add<T>(T left, T right, Func<T, T, T> addFunc) =>
addFunc(left, right);
}
var result = Example.Add(10, 20, (x, y) => x + y);
我经常使用从互联网上盗取的一段代码来实现这个功能。它寻找或构建基本算术运算符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>
源代码由 paste bin 提供: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.
*/
dynamic
关键字的解决方案。 - John Alexiou