Предположим следующий код:
public async Task<IActionResult> Weather(string cityName)
{
if (cityName == null)
{
return View(await _weatherService.GetWeather(cityName));
}
return RedirectToAction("Weather");
}
Я хотел бы реструктурировать код, чтобы использовать оператор переключения, оценивающий выражение await _weatherService.GetWeather(cityName), а затем ссылающийся на него в случаях без необходимости его присвоения. Возможно ли это каким-либо образом или на оцененное выражение, являющееся здесь объектом, нельзя каким-либо образом ссылаться без предварительного его присвоения?
Что я мог сделать (создать условия из объекта, а не из заданного строкового значения:
WeatherConvertedObject w = await _weatherService.GetWeather(cityName);
switch (w)
{
case null: return RedirectToAction("Weather");
case not null: return View(await _weatherService.GetWeather(cityName));
}
Что я хочу сделать (как-то, если это возможно?):
switch (await _weatherService.GetWeather(cityName))
{
case null: return RedirectToAction("Weather");
case not null: return View(this);
//this illustration simply a reference to the evaluated object - this won't compile
}
Я так запутался, о чем здесь спрашивают.
@IanKemp Это просто вопрос о том, можно ли ссылаться на оператор переключения или оценки в последующем создаваемом блоке. Это не должно быть слишком сложно понять — последний блок кода ясно иллюстрирует то, что я хочу сделать, хотя это невозможно. Идея заключается в том, что, поскольку выражение в данный момент оценивается, оно должно быть сохранено где-то в памяти.





Независимо от того, корректен ли ваш поток кода, существует множество способов написать то, что вы хотите, хотя switch не так ли. Один из способов сделать это может быть примерно таким:
if (await _weatherService.GetWeather(cityName) is { } weather) // implied not null
return View(weather);
return RedirectToAction("Weather");
У вас также есть тернарный оператор, чтобы записать его в виде выражения, также основанного на сопоставлении с образцом, как указано выше.
Обновлено: ну, вы также можете написать это с помощью оператора switch (или выражения), если вы действительно хотите:
switch (await _weatherService.GetWeather(cityName))
{
case null: return RedirectToAction("Weather");
case { } weather: return View(weather);
}
Последний блок кода не скомпилировался, поскольку объект weather на самом деле не был определен, и это сразу же ставит вопрос: могу ли я каким-то образом ссылаться на оцениваемый оператор, точно так же, как ключевое слово this можно использовать для других случаев (невозможно в switch ). Это должно быть возможно, поскольку оно хранится где-то в памяти вместе с оцениваемым объектом.
@Aleksandar: Объект weather определяется вторым условием case: для объявления переменной он использует сопоставление с образцом.
@Александар. Шаблон { } weather — это пустой шаблон свойств, который проверяет наличие значения «не null» и присваивает значение новой переменной weather, если результат проверки true. То есть он объявляет эту переменную.
Я бы использовал выражение-переключатель: return await _weatherService.GetWeather(cityName) switch { { } weather => View(weather), _ => RedirectToAction("Weather") }; или троичное выражение: return await _weatherService.GetWeather(cityName) is { } weather ? View(weather) : RedirectToAction("Weather");
@OlivierJacot-Descombes Ребята, вы замечательные — спасибо за помощь!
Я думаю, вы запутали многих людей, включив (вероятно, неправильное) условие в переменную cityName, а затем продолжая игнорировать это условие, когда вы описали поведение, которое вы ищете в своем операторе переключения.
Вы можете переписать свой метод следующим образом:
public async Task<IActionResult> Weather(string cityName)
{
return cityName switch
{
not null when await _weatherService.GetWeather(cityName) is {} w => View(w),
_ => RedirectToAction("Weather")
};
}
Обратите внимание, что это исправляет то, что, по моему мнению, было ошибкой в исходном коде, используя имя города, когда оно не равно нулю. Я также использую выражения переключения, а не операторы переключения.
Что ж, если бы они вместо этого прочитали весь вопрос, они бы поняли, о чем я спрашиваю. Этот вопрос не имеет ничего общего с именем переменной cityName, и я думаю, что я совершенно ясно выразился по этому поводу.
Люди, которые привыкли отвечать на вопросы Stack Overflow, в комментариях к вашему вопросу оказались в замешательстве. Я думаю, можно предположить, что они просто не прочитали весь ваш вопрос. Я рад, что вы получили ответ, который искали. Я просто говорю, что в будущем вы сможете добиться этого быстрее, сузив информацию, которой вы делитесь, до тех частей, которые вас интересуют.
В C# нет ничего подобного тому, что вы спрашиваете, и код, который вы пытаетесь написать, не является идиоматическим. Первый случай, который вы представите, должен быть
return View(w);в любом сценарии.