代码之家  ›  专栏  ›  技术社区  ›  blackwing

.NET泛型中重载运算符约束的解决方案

  •  32
  • blackwing  · 技术社区  · 16 年前

    如果我想要一个只接受重载了一个运算符的类型的泛型方法,比如减法运算符,我该怎么做呢?我尝试使用接口作为约束,但接口不能有运算符重载。

    实现这一目标的最佳方法是什么?

    3 回复  |  直到 9 年前
        1
  •  42
  •   Marc Gravell    15 年前

    没有直接的答案;运算符是静态的,不能用约束来表示-并且现有的primary不实现任何特定的接口(与可用于模拟大于/小于的IComparable[<t>]不同)。

    但是,如果您只想让它工作,那么在.NET 3.5中有一些选项…

    我建了一个图书馆 here 它允许高效、简单地访问具有泛型的运算符,例如:

    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>; 通过所有的方法,这会变得混乱。

        2
  •  9
  •   YellPika    13 年前

    我发现我可以很好地处理这个问题。前任。

    ldarg.0
    ldarg.1
    add
    ret
    

    在泛型方法中编译,只要指定基元类型,代码就可以正常运行。可以扩展它来调用非基元类型上的运算符函数。

    here .

        3
  •  -1
  •   John Alexiou    9 年前

    有一段从互联网上偷来的代码,我用了很多。它使用 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"
        }
    }
    

    操作<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. 
     */