解决方案在.NET泛型重载操作约束解决方案在.NET泛型重载操作约束(Solution for ov

2019-05-05 06:49发布

如果我想有只接受已重载操作类型,例如减法运算符的通用方法,我会怎么做。 我试图用一个接口作为约束,但接口不能有运算符重载。

什么是实现这一目标的最佳途径?

Answer 1:

有没有直接的答案; 运营商是静态的,并且不能在约束来表达 - 和现有primatives不实现任何特定的接口(对比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>; 在所有的方法,这就会变得混乱。



Answer 2:

我发现,IL实际上可以处理这个非常好。 防爆。

ldarg.0
ldarg.1
add
ret

在一个通用的方法的经编译的代码将只要指定一个基本类型细运行。 它可能会延长本调用非原始类型操作者的功能。

见这里 。



Answer 3:

有从我用了很多这样做的internats被盗的一段代码。 它会查找或使用建立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. 
 */


文章来源: Solution for overloaded operator constraint in .NET generics