Відповідь нижче була написана років тому і оновлювалася з часом. Станом на C # 7 ви можете використовувати відповідність шаблонів:
if (animal is Dog dog)
{
// Use dog here
}
Зауважте, що dog
після if
виписки все ще існує, але не визначено.
Ні, немає. Це набагато ідіоматичніше:
Dog dog = animal as Dog;
if (dog != null)
{
// Use dog
}
З огляду на те, що майже завжди використовується такий спосіб "з наступним, якщо" , може бути більше сенсу існувати оператор, який виконує обидві частини за один раз. Наразі це не в C # 6, але може бути частиною C # 7, якщо реалізована пропозиція щодо узгодження шаблонів .
Проблема полягає в тому, що ви не можете оголосити змінну в частині умови if
заяви 1 . Найближчий підхід, про який я можу придумати, такий:
// EVIL EVIL EVIL. DO NOT USE.
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 => {
// Use dog in here
});
Як варіант, ви можете комбінувати два:
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);
}
}
Ви також можете використовувати метод розширення без лямбда-виразу більш чистим способом, ніж цикл 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>())
{
// use dog
}
1 Ви можете призначити значення у if
висловлюваннях, хоча я це рідко роблю. Це не те саме, що декларувати змінні. Мені не страшно незвично це робити, while
хоча читаючи потоки даних. Наприклад:
string line;
while ((line = reader.ReadLine()) != null)
{
...
}
У ці дні я зазвичай вважаю за краще використовувати обгортку, яка дозволяє мені використовувати, foreach (string line in ...)
але я розглядаю вище як досить ідіоматичну схему. Це , як правило , не приємно мати побічні ефекти в межах стану, але альтернативи , як правило , включають дублювання коду, і якщо ви знаєте цю модель легко отримати право.
bool
умова?