2016-03-23 20 views
1

Ich möchte eine generische Funktion schreiben, die einen generischen Parameter an eine Funktion übergibt, die mehrere Überladungen hat. Das C++ Äquivalent wäre this. Hier ist, was ich versucht:einen generischen Typ an eine Methode übergeben

public void setUniform1<T>(int loc, T value) { 
    GL.Uniform1(loc, value); 
} 

aber das gibt mir den Fehler

error CS1503: Argument 2: cannot convert from 'T' to 'double'

GL.Uniform1 mehrere Typen für den Wert Paramter nimmt und ich denke, doppelt so hoch ist die erste Überlast, das ist, warum es versucht, zu konvertieren doppelt.

Also, wie mache ich das?

+0

Versuchen Sie '((dynamische) GL) .Uniform1 (loc, Wert);' –

+0

@YacoubMassad: Dies gibt mir den Fehler: 'Fehler CS0119: 'GL' ist ein Typ, der im angegebenen Kontext nicht gültig ist . Ich denke, GL ist kein Namensraum, sondern eine statische Klasse. – gartenriese

+1

versuchen 'GL.Uniform1 (loc, (double) (Objekt) Wert)' – esiprogrammer

Antwort

2

C++ - Vorlagen und .NET-Generics sehen nur gleich aus, verhalten sich jedoch anders: .NET-Generika müssen zur Kompilierzeit vollständig auflösbar sein. In Ihrem Beispiel ist das nicht möglich.

Sie können ein ähnliches Ergebnis zu C++ Vorlagen mit dem dynamic Stichwort erreichen:

public void setUniform1<T>(int loc, T value) { 
    GL.Uniform1(loc, (dynamic)value); 
} 

Dies wird die Überladungsauflösung auf die Laufzeit, bei der die Art von value Punkt verschieben tatsächlich bekannt ist.
Aber dies hat das Problem, dass es eine Ausnahme auslösen wird, wenn keine Überlastung von GL.Uniform1 für den Typ value vorliegt.
Dennoch habe ich diesen genauen Ansatz ein paar Mal verwendet. Es macht Sinn, wenn Sie sicher sein können, dass Sie nur eine bestimmte Menge von Typen erhalten und für alle eine Überladung haben.
Eine andere Lösung zur Vermeidung der Laufzeitausnahme wäre das Bereitstellen einer Überladung, die object dauert und eine Standardaktion ausführt.

+0

Das Schlüsselwort 'dynamic' ist riskant und kann Laufzeitfehler verursachen. Wenn etwas anderes als ein Typ, den "GL.Uniform1" akzeptiert, übergeben wird, wird es geworfen. –

+2

@DavidPine: Ja, deshalb habe ich die Fehler unter dem Code erklärt. –

+0

Können Sie erweitern auf "Eine andere Lösung, um die Laufzeit Ausnahme zu vermeiden wäre eine Überladung, die Objekt und führt eine Standardaktion."? – gartenriese

1

Vielleicht sollten Sie stattdessen ein Double übergeben, da dies Ihre Funktion benötigt.

Generische Typen sind nur nützlich, wenn Sie keinen bestimmten Datentyp benötigen, aber in diesem Fall tun Sie dies.


C# hat keine numeric generic type constraint.

Angesichts der Tatsache, dass es mehrere Versionen von GL.Uniform gibt, von denen jede einen bestimmten Datentyp annimmt, würden Sie normalerweise drei Versionen der Funktion benötigen.

Da jedoch sowohl Float als auch Int ohne Genauigkeitsverlust in ein Double konvertiert werden können, könnten Sie wahrscheinlich nur mit einer Funktion (doppelt) auskommen.

int i; 
    float f; 
    double d; 

    setUniform1(loc, i); // implicit conversion int => double 
    setUniform1(loc, f); // implicit conversion float => double 
    setUniform1(loc, d); 

Siehe Implicit Numeric Conversions.

+0

Nein, GL.Uniform1 kann auch ein float oder ein int, nicht nur ein Doppel. Wenn es nur ein Doppel wäre, würde ich keine generische Methode brauchen. – gartenriese

+0

@gartenriese Ich bin mir nicht sicher, ob Sie tatsächlich eine generische Methode brauchen. Sie könnten durch Ihren C++ - Hintergrund und ihre Vorlagen beeinflusst sein. Wie nennst du eigentlich 'setUniform1'? Woher kommen die Werte, von denen du kommst? –

+0

@DanielHilgarth: Ich möchte 'setUniform1' entweder mit int, float oder double aufrufen. Es wird auch eine 'setUniform2' geben, die andere Typen verwendet und GL.Uniform2 aufruft. Ich dachte, es könnte mich davor bewahren, alle Methoden für jeden Typ zu kopieren und einzufügen. – gartenriese

Verwandte Themen