Ответ ниже был написан много лет назад и со временем обновлялся. Начиная с C # 7, вы можете использовать сопоставление с образцом:
if (animal is Dog dog)
{
}
Обратите внимание, что dog
это все еще находится в области действия после if
оператора, но не определено.
Нет, нет. Однако более идиоматично написать это:
Dog dog = animal as Dog;
if (dog != null)
{
}
Учитывая, что «как следует за условием» почти всегда используется таким образом, было бы целесообразнее использовать оператор, выполняющий обе части за один раз. В настоящее время этого нет в C # 6, но может быть частью C # 7, если реализовано предложение сопоставления с образцом .
Проблема в том, что вы не можете объявить переменную в условной части if
оператора 1 . Самый близкий подход, который я могу придумать, таков:
for (Dog dog = animal as Dog; dog != null; dog = null)
{
...
}
Это просто противно ... (Я только что попробовал, и это работает. Но, пожалуйста, не делайте этого. О, и вы, конечно, можете объявить dog
использование var
).
Конечно, вы можете написать метод расширения:
public static void AsIf<T>(this object value, Action<T> action) where T : class
{
T t = value as T;
if (t != null)
{
action(t);
}
}
Затем вызовите его с помощью:
animal.AsIf<Dog>(dog => {
});
В качестве альтернативы вы можете объединить два:
public static void AsIf<T>(this object value, Action<T> action) where T : class
{
for (var t = value as T; t != null; t = null)
{
action(t);
}
}
Вы также можете использовать метод расширения без лямбда-выражения более чистым способом, чем цикл for:
public static IEnumerable<T> AsOrEmpty(this object value)
{
T t = value as T;
if (t != null)
{
yield return t;
}
}
Затем:
foreach (Dog dog in animal.AsOrEmpty<Dog>())
{
}
1 Вы можете присваивать значения в if
операторах, хотя я редко это делаю. Однако это не то же самое, что объявление переменных. Это не очень необычно для меня , чтобы сделать это в while
хотя , когда чтение потоков данных. Например:
string line;
while ((line = reader.ReadLine()) != null)
{
...
}
В наши дни я обычно предпочитаю использовать оболочку, которая позволяет мне использовать, foreach (string line in ...)
но я рассматриваю вышесказанное как довольно идиоматический шаблон. Это , как правило , не приятно иметь побочные эффекты в пределах состояния, но альтернативы , как правило , включают дублирование кода, и если вы знаете эту модель легко получить право.
bool
состоянии?