Es gibt drei Grund, warum Ihr Code wird nicht funktionieren..
- Ihre generische Einschränkung erfordert, dass die Art sowohl erbt von
double
und long
die nicht möglich ist
double
und long
können nicht als generische Einschränkungen verwendet werden, weil sie verschlossen sind.
- Es gibt keine implizite Konvertierung von
double
an einen unbekannten Typ
Es gibt kein „fix“ für die ersten beiden. Das Update für das letzte wäre object
zuerst zu werfen:
if (isDouble)
{
T Value = (T)(object)2.5; // does not compile
Result.Add(Value);
}
else
{
T Value = (T)(object)2; // does not compile
Result.Add(Value);
}
Es gibt keine Möglichkeit, die Methode zu bekommen genau so, wie Sie es wollen arbeiten, weil es keine Möglichkeit gibt T
zu beschränken entweder double
zu sein oder long
. Sie könnte inspizieren den Typ mit Reflektion und eine Ausnahme auslösen, wenn es nicht einer von diesen ist, aber es gibt keine Möglichkeit, das zum Zeitpunkt der Kompilierung erzwingen.
Das Kernproblem ist, dass Ihr Code nicht generisch ist. Wahrer generischer Code interessiert nicht, was T
ist (modulo einige sehr breite Parameter, wie es einige Schnittstelle implementieren muss). Die Anrufer bekommt zu bestimmen, was T
ist, nicht die Methode, so dass alles, was unterschiedliche Logik basierend auf der tatsächlichen Art von T
ist in der Regel ein Code Geruch. Dies scheint nur eine Lernübung zu sein, aber wenn Sie diese Funktion im wirklichen Leben benötigt würde ich empfehlen, zwei verschiedene Methoden mit:
private IList<double> GetDoubleList()
{
IList<double> Result = new List<double>();
double Value = 2.5;
Result.Add(Value);
return Result;
}
private IList<long> GetLongList()
{
IList<long> Result = new List<long>();
long Value = 2;
Result.Add(Value);
return Result;
}
Es ist nicht , die viel mehr als das, was Sie begann mit, es ist ein bisschen von der Wiederholung, aber nicht viel, es ist völlig typsicher, und es gibt keine Art Ambiguität innerhalb der Methoden.
Als nächstes können Sie den redundanten Code in eine generische Methode Refactoring (in diesem Fall brauchen Sie es nicht zu beschränken, da Sie die Typen aus dem Rufmethode steuern):
private IList<T> GetList<T>(T Value)
{
IList<T> Result = new List<T>();
Result.Add(Value);
return Result;
}
private IList<double> GetDoubleList()
{
return GetList<double>(2.5);
}
private IList<long> GetLongList()
{
return GetList<long>(2);
}
Es gibt keinen Grund, warum Sie isDouble als arg bereitstellen müssten; Der Typ von T kann zur Laufzeit bestimmt werden: 'Type typeParameterType = typeof (T);' –
': double, long' bedeutet double * und * long - d. h. es ist unsinnig. – Blorgbeard
Die generischen Einschränkungen sind UND, nicht ODER. Also T in Ihrem Fall muss sowohl doppelt als auch lang sein, was unwahrscheinlich erscheint ..! – Chris