Lösung für überladenen Operator Einschränkung in .NET Generika
-
02-07-2019 - |
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?
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 [
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
erstelleninterface 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.
*/