A resposta abaixo foi escrita anos atrás e atualizada ao longo do tempo. No C # 7, você pode usar a correspondência de padrões:
if (animal is Dog dog)
{
// Use dog here
}
Observe que dog
ainda está no escopo após a if
instrução, mas não está definitivamente atribuído.
Não, não existe. É mais idiomático escrever isso:
Dog dog = animal as Dog;
if (dog != null)
{
// Use dog
}
Dado que "como seguido de se" é quase sempre usado dessa maneira, pode fazer mais sentido haver um operador que execute as duas partes de uma só vez. No momento, isso não está no C # 6, mas pode fazer parte do C # 7, se a proposta de correspondência de padrões for implementada.
O problema é que você não pode declarar uma variável na parte da condição de uma if
instrução 1 . A abordagem mais próxima que consigo pensar é a seguinte:
// EVIL EVIL EVIL. DO NOT USE.
for (Dog dog = animal as Dog; dog != null; dog = null)
{
...
}
Isso é desagradável ... (Eu apenas tentei, e funciona. Mas, por favor, não faça isso. Ah, e você pode declarar dog
usando, é var
claro).
Claro que você pode escrever um método de extensão:
public static void AsIf<T>(this object value, Action<T> action) where T : class
{
T t = value as T;
if (t != null)
{
action(t);
}
}
Em seguida, chame-o com:
animal.AsIf<Dog>(dog => {
// Use dog in here
});
Como alternativa, você pode combinar os dois:
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);
}
}
Você também pode usar um método de extensão sem uma expressão lambda de maneira mais limpa que o loop for:
public static IEnumerable<T> AsOrEmpty(this object value)
{
T t = value as T;
if (t != null)
{
yield return t;
}
}
Então:
foreach (Dog dog in animal.AsOrEmpty<Dog>())
{
// use dog
}
1 Você pode atribuir valores em if
declarações, embora raramente o faça. Isso não é o mesmo que declarar variáveis. Não é muito incomum para mim fazê-lo de uma vez while
ao ler fluxos de dados. Por exemplo:
string line;
while ((line = reader.ReadLine()) != null)
{
...
}
Hoje em dia, normalmente prefiro usar um invólucro que me permita usar, foreach (string line in ...)
mas vejo o acima como um padrão bastante idiomático. É geralmente não bom ter efeitos colaterais dentro de uma condição, mas as alternativas geralmente envolvem a duplicação de código, e quando você sabe que este padrão é fácil de acertar.
bool
condição?