2017-01-23 6 views
0

Ich habe eine Struktur, die wie folgt aussieht:C# Operator Overloading Generisches der Subclass Mit

public struct Vector2d<T> where T : Unit { 
    public double x; 
    public double y; 

    ... 

    public static Vector2d<Length> operator * (Vector2d<Speed> speed, Vector2d<Duration> duration) { 
     return new Vector2d<Length>(speed.x * duration.x, speed.y * duration.y); 
    } 
} 

die Länge, Geschwindigkeit und Dauer-Typen sind alle Subtypen der Einheit. (T von Einheit erbt auch)

jedoch der Compiler sagt:

One of the parameters of a binary operator must be the containing type.

Das erscheint mir seltsam, weil die zur Verfügung gestellten Typen Unterklassen des enthaltenden Typs sind.

Warum ist das, was ich versuche, illegal zu machen?

Ich weiß Vector2 ist keine Unterklasse von Vector2, aber ich versuche nicht, die Werte des generischen Typs zu verwenden. Alle im Operator verwendeten Daten sind die Vector2-Klasse.

+0

Es ist illegal, weil die Sprachdesigner es illegal gemacht haben. Die Fehlermeldung informiert Sie genau über die Einschränkung, die die C# -Spezifikation beschreibt. Der Compiler folgt nur der Spezifikation. Wenn Sie wissen wollen "warum?" Sie müssen die Sprachdesigner fragen, und selbst dann kann ihre Argumentation in erster Linie auf ihrer eigenen Meinung beruhen. –

+0

Nicht sicher, warum diese Frage abgelehnt wurde ... perfekt gültige Frage mit Code und klarer Frage. +1 von mir. – CodingYoshi

+0

Ich empfehle den Versuch, Unit-Analyse über Generika darzustellen. Einheiten sind die Art von Dingen, die wirklich in die Sprache eingebaut werden müssen. Siehe zum Beispiel F # 's Einheitentyp Anmerkungen. https://docs.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/units-of-measure –

Antwort

0

Nach dem MSDN page für diesen Fehler:

A definition of a binary operator specifies both parameters with types other than that of the class or structure in which the operator is defined. When you define an operator in a class or structure, at least one of the parameters must be of the type of that class or structure.

In Ihrem Fall Ihre Betreiber nicht die Verwendung eines Vector2d<T> Art machen (Sie verwenden Vector2d<Speed> und Vector2d<Duration>

+0

Also muss der Operator auf alle Instanzen des Typs anwenden, nicht nur eine Teilmenge. Ich habs. – tbg10101

0

Operatoren arbeiten mit Instanzen. B.:

string one = new string(new char[] { 'o', 'n', 'e' }); 
string two = new string(new char[] { 't', 'w', 'o' }); 
if (one == two) { // do something... }; 

Der Grund, ich bin in der Lage zu uns e == ist, weil es in String Klasse implementiert ist.

Sie haben auch einen Operator in Ihrer Klasse. Also lass es uns benutzen. Aber dazu muss ich eine Instanz von Vector2d<T> erstellen und da es ein offener Typ ist, muss ich es während der Instanziierung schließen.

Also lassen Sie uns dies zuerst tun:

public class MyClass : Unit 
{ 
} 

Lassen Sie uns nun eine Instanz Ihrer Struktur erstellen:

var inst1 = new Vector2d<MyClass>(); 
var inst2 = new Vector2d<MyClass>(); 

Das funktioniert, weil MyClass die Einschränkung ist vorbei, dass T von Unit ableiten müssen. Ok jetzt werde ich den Operator verwenden:

// Ooops MyClass is not Speed or Duration 
var result = inst1 * inst2; 

Das ist genau, warum der Compiler diese Regel erzwingt, weil sie will der Betreiber sicherstellen, dass auf der Instanz des Typs arbeiten kann.

In Ihrem Fall können Sie nur den Operator für Vector2d<T> wie folgt definieren:

public struct Vector2d<T> where T : Unit 
{ 
    public double x; 
    public double y; 

    public Vector2d(double x, double y) 
    { 
     this.x = x; 
     this.y = y; 
    } 

    public static Vector2d<T> operator *(Vector2d<T> speed, Vector2d<T> duration) 
    { 
     return new Vector2d<T>(speed.x * duration.x, speed.y * duration.y); 
    } 
} 

Darüber hinaus Ihr Netzbetreiber, die Art und Weise haben Sie es überhaupt nicht generisch ist. Es benutzt Speed, Duration und Length, also arbeiten Sie mit diesen Typen.

Der Fehler Einer der Parameter eines binären Operators muss der umgebende Typ sein. ist der Weg des Compilers, uns davon abzuhalten, in solche Schwierigkeiten zu geraten. Wir sollten dankbar sein!