Frage

Was würde ich tun, wenn ich eine generische Methode haben will, die nur Typen akzeptiert, die einen Betreiber überlastet haben, zum Beispiel der Subtraktionsoperator. Ich habe versucht, eine Schnittstelle als Einschränkung verwenden, aber Schnittstellen können nicht Überladen von Operatoren haben.

Was ist der beste Weg, um dies zu erreichen?

War es hilfreich?

Lösung

Es gibt keine unmittelbare Antwort; Betreiber sind statisch und können nicht in Constraints ausgedrückt werden. - und die vorhandenen primatives implementieren keine spezifische Schnittstelle (Gegensatz zu IComparable [], die verwendet werden können, Größer-als / weniger als zu emulieren)

Allerdings; wenn Sie nur wollen, dass es funktioniert, dann in .NET 3.5 gibt es einige Optionen ...

Ich habe zusammen eine Bibliothek setzen hier , dass eine effiziente erlaubt und einfacher Zugang zu Betreibern mit Generika - wie zum Beispiel:

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

Es kann als Teil der MiscUtil

heruntergeladen werden

Zusätzlich wird in C # 4.0, dies wird möglich, über dynamic:

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

Ich habe auch (an einer Stelle) eine .NET 2.0-Version, aber das ist weniger getestet. Die andere Option ist eine Schnittstelle wie

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

etc, aber dann müssen Sie einen ICalc<T>; durch alle Methoden zu übergeben, die chaotisch wird.

Andere Tipps

Ich fand, dass IL dies tatsächlich umgehen kann ganz gut. Ex.

ldarg.0
ldarg.1
add
ret

Zusammengestellt in einem allgemeinen Verfahren wird der Code ausgeführt in Ordnung, solange ein primitiver Typ angegeben ist. Es kann möglich sein, dies zu erweitern Bedienfunktionen auf nicht-primitiven Typen zu nennen.

Siehe hier .

Es ist ein Stück Code aus den Internaten gestohlen, dass ich viel für diese. Es sucht nach oder baut IL grundlegenden arithmetischen Operatoren. Es ist alles in einem Operation<T> generische Klasse gemacht, und alles, was Sie tun müssen, ist die erforderliche Operation in einen Delegierten zuweisen. Wie add = Operation<double>.Add.

Es wird wie folgt verwendet:

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> Quellcode mit freundlicher Genehmigung von Paste ist: http://pastebin.com/nuqdeY8z

mit Zuschreibung unter:

/* 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. 
 */
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top