Hier können wir die folgenden Klassen sagen:einen generischen Typ ohne Einschränkung bestanden mit mit einem eingeschränkten generischen Typ
public interface IFrobnicator<T> { }
class ComparableFrobnicator<T> : IFrobnicator<T> where T : IComparable<T>
{
public ComparableFrobnicator(T value) { }
}
class EquatableFrobnicator<T> : IFrobnicator<T> where T : IEquatable<T>
{
public EquatableFrobnicator(T value) { }
}
Sie Methoden schreiben
public IFrobnicator<T> MakeFrobnicatorFromComparable<T>(T value) where T : IComparable<T>
{
return new ComparableFrobnicator<T>(value);
}
public IFrobnicator<T> MakeFrobnicatorFromEquatable<T>(T value) where T : IEquatable<T>
{
return new EquatableFrobnicator<T>(value);
}
Wenn ich das in einem einzigen vereinen wollte Methode, der naheliegendste Weg wird nicht kompilieren:
Das löst den folgenden Fehler beim Compi LED:
CS0314 Der Typ 'T' kann nicht als Typparameter 'T' im generischen Typ oder in der Methode 'UserQuery.ComparableFrobnicator' verwendet werden. Es gibt keine Box-Konvertierung oder Typ-Parameter-Konvertierung von 'T' nach 'System.IComparable'.
ich nicht new ComparableFrobnicator <T>
mit new ComparableFrobnicator<IComparable<T>>
ersetzen können, da die Probleme auf der ganzen Linie verursacht mit value
wieder heraus bekommen - Sie können aus einem Schnittstellentyp auf einen konkreten Typ nicht gegossen.
Anstatt also ging ich den Weg der Reflexion:
public IFrobnicator<T> MakeFrobnicator<T>(T value)
{
if (value is IComparable<T>)
{
var constructor = typeof(ComparableFrobnicator<>).MakeGenericType(typeof(T)).GetConstructor(new[] { typeof(T) });
return (IFrobnicator<T>)constructor.Invoke(new object[] { value});
}
else if (value is IEquatable<T>)
{
var constructor = typeof(EquatableFrobnicator<>).MakeGenericType(typeof(T)).GetConstructor(new[] { typeof(T) });
return (IFrobnicator<T>)constructor.Invoke(new object[] { value });
}
else throw new ArgumentException();
}
, die perfekt zu funktionieren scheint, aber sieht aus wie ein Schritt zurück in einer Sprache mit solchen leistungsfähigen Typinferenz als ich gewohnt bin. Gibt es etwas, das mir fehlt oder eine bessere Technik, die ich vermisst habe?
In Ihrem kombinierten Verfahren zu lösen, ist Wert vom Typ T als Parameter, dann Sie sehen, ob der Wert ist IComparable oder IEquatable . Da stimmt etwas nicht. –
David
@ David z.B. 'int', ist' IComparable '* und *' IEquatable '. Ein Typ, der komplexe Zahlen repräsentiert, könnte mit sich selbst vergleichbar sein, aber nicht vergleichbar. –
RoadieRich
Es scheint, dass die letzte Methode auf die IComparable –