Die folgende Antwort wurde vor Jahren geschrieben und im Laufe der Zeit aktualisiert. Ab C # 7 können Sie den Mustervergleich verwenden:
if (animal is Dog dog)
{
// Use dog here
}
Beachten Sie, dass dies dog
nach der if
Anweisung noch im Geltungsbereich liegt , aber nicht definitiv zugewiesen ist.
Nein, gibt es nicht. Es ist jedoch idiomatischer, dies zu schreiben:
Dog dog = animal as Dog;
if (dog != null)
{
// Use dog
}
Angesichts der Tatsache, dass "wie folgt von if" fast immer auf diese Weise verwendet wird, ist es möglicherweise sinnvoller, dass es einen Bediener gibt, der beide Teile auf einmal ausführt. Dies ist derzeit nicht in C # 6 enthalten, kann jedoch Teil von C # 7 sein, wenn der Mustervergleichsvorschlag implementiert ist.
Das Problem ist, dass Sie im Bedingungsteil einer Anweisung 1 keine Variable deklarieren können . Der nächste Ansatz, den ich mir vorstellen kann, ist folgender:if
// EVIL EVIL EVIL. DO NOT USE.
for (Dog dog = animal as Dog; dog != null; dog = null)
{
...
}
Das ist nur böse ... (Ich habe es gerade versucht und es funktioniert. Aber bitte, bitte tu das nicht. Oh, und du kannst natürlich die dog
Verwendung deklarieren var
.)
Natürlich können Sie eine Erweiterungsmethode schreiben:
public static void AsIf<T>(this object value, Action<T> action) where T : class
{
T t = value as T;
if (t != null)
{
action(t);
}
}
Dann nenne es mit:
animal.AsIf<Dog>(dog => {
// Use dog in here
});
Alternativ können Sie beide kombinieren:
public static void AsIf<T>(this object value, Action<T> action) where T : class
{
// EVIL EVIL EVIL
for (var t = value as T; t != null; t = null)
{
action(t);
}
}
Sie können auch eine Erweiterungsmethode ohne Lambda-Ausdruck sauberer als die for-Schleife verwenden:
public static IEnumerable<T> AsOrEmpty(this object value)
{
T t = value as T;
if (t != null)
{
yield return t;
}
}
Dann:
foreach (Dog dog in animal.AsOrEmpty<Dog>())
{
// use dog
}
1 Sie können Werte in Anweisungen zuweisenif
, obwohl ich dies selten tue. Das ist jedoch nicht dasselbe wie das Deklarieren von Variablen. Es ist nicht sonderlich ungewöhnlich für mich, dies while
beim Lesen von Datenströmen zu tun . Beispielsweise:
string line;
while ((line = reader.ReadLine()) != null)
{
...
}
Heutzutage bevorzuge ich normalerweise die Verwendung eines Wrappers, mit dem ich ihn verwenden kann, foreach (string line in ...)
aber ich betrachte das Obige als ein ziemlich idiomatisches Muster. Es ist normalerweise nicht schön, Nebenwirkungen innerhalb einer Bedingung zu haben, aber die Alternativen beinhalten normalerweise eine Codeduplizierung, und wenn Sie dieses Muster kennen, ist es einfach, es richtig zu machen.
bool
Zustand?