La respuesta a continuación se escribió hace años y se actualizó con el tiempo. A partir de C # 7, puede usar la coincidencia de patrones:
if (animal is Dog dog)
{
// Use dog here
}
Tenga en cuenta que dog
todavía está dentro del alcance después de la if
declaración, pero definitivamente no está asignado.
No, no hay Sin embargo, es más idiomático escribir esto:
Dog dog = animal as Dog;
if (dog != null)
{
// Use dog
}
Dado que "como seguido por if" casi siempre se usa de esta manera, podría tener más sentido que haya un operador que realice ambas partes de una sola vez. Esto no está actualmente en C # 6, pero puede ser parte de C # 7, si se implementa la propuesta de coincidencia de patrones .
El problema es que no puede declarar una variable en la parte de condición de una if
instrucción 1 . El enfoque más cercano que se me ocurre es este:
// EVIL EVIL EVIL. DO NOT USE.
for (Dog dog = animal as Dog; dog != null; dog = null)
{
...
}
Eso es desagradable ... (Acabo de probarlo y funciona. Pero, por favor, no hagas esto. Ah, y puedes declararlo dog
usando, var
por supuesto).
Por supuesto, podrías escribir un método de extensión:
public static void AsIf<T>(this object value, Action<T> action) where T : class
{
T t = value as T;
if (t != null)
{
action(t);
}
}
Luego llámalo con:
animal.AsIf<Dog>(dog => {
// Use dog in here
});
Alternativamente, puede combinar los dos:
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);
}
}
También puede usar un método de extensión sin una expresión lambda de una manera más limpia que el ciclo for:
public static IEnumerable<T> AsOrEmpty(this object value)
{
T t = value as T;
if (t != null)
{
yield return t;
}
}
Luego:
foreach (Dog dog in animal.AsOrEmpty<Dog>())
{
// use dog
}
1 Puede asignar valores en las if
declaraciones, aunque rara vez lo hago. Sin embargo, eso no es lo mismo que declarar variables. No es terriblemente inusual que lo haga en un momento while
cuando leo flujos de datos. Por ejemplo:
string line;
while ((line = reader.ReadLine()) != null)
{
...
}
En estos días, normalmente prefiero usar un contenedor que me permita usar, foreach (string line in ...)
pero veo lo anterior como un patrón bastante idiomático. Por lo general, no es bueno tener efectos secundarios dentro de una afección, pero las alternativas generalmente implican la duplicación de código, y cuando conoce este patrón, es fácil acertar.
bool
condición?