Dies ist wahrscheinlich eine Anfängerfrage, aber Google hat überraschenderweise keine Antwort geliefert.
Ich habe diese eher künstliche Methode
T HowToCast<T>(T t)
{
if (typeof(T) == typeof(string))
{
T newT1 = "some text";
T newT2 = (string)t;
}
return t;
}
Ich komme aus einem C ++ - Hintergrund und habe erwartet, dass dies funktioniert. Es kann jedoch nicht mit "Typ 'T' kann nicht implizit in Zeichenfolge konvertiert werden" und "Typ 'T' kann nicht in Zeichenfolge konvertiert werden" für beide oben genannten Zuweisungen kompiliert werden.
Ich mache entweder konzeptionell etwas falsch oder habe einfach die falsche Syntax. Bitte helfen Sie mir, das zu klären.
Danke dir!
typeof(T) == typeof(string)
wird zur Laufzeit und nicht zur Kompilierungszeit aufgelöst. Somit ist die folgende Zeile im Block ungültig.Antworten:
Auch wenn es innerhalb eines ist
if
Block, wird der Compiler weiß nicht , dassT
iststring
.Daher können Sie nicht wirken. (Aus dem gleichen Grund , dass Sie nicht werfen kann
DateTime
zustring
)Sie müssen zu
object
(zu dem jederT
wechseln kann) und von dort zustring
(seit)object
kann zu geworfen werdenstring
).Beispielsweise:
quelle
T
:var isBlank = (userDefinedValue is string) && String.IsNullOrWhiteSpace(userDefinedValue as string);
Beide Leitungen haben das gleiche Problem
Der Compiler weiß nicht, dass T eine Zeichenfolge ist, und kann daher nicht wissen, wie er diese zuweisen soll. Aber da Sie überprüft haben, können Sie es einfach mit erzwingen
Sie müssen das t nicht umwandeln, da es bereits eine Zeichenfolge ist. Außerdem müssen Sie die Einschränkung hinzufügen
quelle
Ich kenne einen ähnlichen Code, den das OP in dieser Frage von generischen Parsern gepostet hat. Aus Sicht der Leistung sollten Sie diese verwenden
Unsafe.As<TFrom, TResult>(ref TFrom source)
, die im System.Runtime.CompilerServices.Unsafe NuGet-Paket enthalten ist. In diesen Szenarien wird das Boxen für Werttypen vermieden. Ich denke auch, dass dies dazuUnsafe.As
führt , dass weniger Maschinencode von der JIT erzeugt wird als zweimal (mit(TResult) (object) actualString
), aber ich habe das nicht überprüft.Unsafe.As
wird durch die JIT durch effiziente Maschinencode-Anweisungen ersetzt, wie Sie im offiziellen CoreFX-Repo sehen können:quelle
Wenn Sie nach expliziten Typen suchen, warum deklarieren Sie diese Variablen als
T
's'?quelle
T
.object
Werte gespeichertstring
werden , und abgeleitete Typen, in denen Werte gespeichert werden. Angenommen, diese Felder haben auch den Wert "DefaultIfNotProvided". Sie müssen also überprüfen, ob der vom Benutzer angegebene Wert (der ein Objekt, eine Zeichenfolge oder sogar ein numerisches Grundelement sein kann) äquivalent istdefault(T)
. Eine Zeichenfolge kann als Sonderfall behandelt werden, in dem eine leere Zeichenfolge / Leerzeichen genauso behandelt wird wie die Standardeinstellung (T). Daher möchten Sie möglicherweise überprüfen, obT userValue; var isBlank = (userValue is string) && String.IsNullOrWhitespace(userValue as string);
.Sie erhalten diesen Fehler auch, wenn Sie eine generische Deklaration für Ihre Klasse und Ihre Methode haben. Der unten gezeigte Code gibt beispielsweise diesen Kompilierungsfehler aus.
Dieser Code wird kompiliert (Hinweis T aus der Methodendeklaration entfernt):
quelle
Ändern Sie diese Zeile:
Für diese Zeile:
quelle