Написать класс для switch?
Написать класс для switch?
Дано:
класс TModel.
public class Model{private const string _R33 = "R33";private const string _R34 = "R34";
private readonly string ModelValue;
private Model(string pModelValue){ModelValue = pModelValue;}public static Model R33 = new Model(_R33);public static Model Р34 = new Model(_R34);....
}
помимо указанного еще имплементируются операции сравнения... и немножко функций.
Все с целью возможности написания в коде:
Model currentModel = null;
if(currentMode == Model.R33) { ... }
все хорошо, все работает как должнО.
Однако есть дополнительная потребность использовать currentModel в операторе switch.
Т.е. хочется что-то вида
switch(currentModel)
{
case Model.R33:
....
break;
case Model.R34:
....
break;
}
Что-то у меня никак это не получается. Есть идеи как сделать?
У тебя как всегда жесть :)
-----
Ну а зачем по-другому? :)
У switch'а в case'е должна быть константа.
-----
Разумеется.
Я могу даже для простоты поменять доступ на паблик к _Rxx-констанстантам в классе для case TModel._R33:
Но решение, которое меня интересует, заключается в использовании инстанса класса TModel в качестве константы.
Т.е. интересует именно так, как написано - case TModel.R33:
Ну не хватает мне в шарпе плюснотого помещающего синтаксиса...
Это все, разумеется, прочитано и понятно.
Остальные ограничения, как:
- енум не имеет функций
- статический элемент не является константой
- инстансе класса не является константой
- и т.п.
Все - понятно.
НО! Все, что представляет собой требуемый класс является или может быть представлено, типом инт/стринг с дополнительной функциональностью.
Вопрос - как обойти? - разумеется, сохранив нужный формат записи.
Проще говоря - Как сказать системе, что R33 & R34 есть суть константы расширенного типа инт/стринг?
Базис для этого есть - енум.
НО! Все, что представляет собой требуемый класс является или может быть представлено, типом инт/стринг с дополнительной функциональностью.
Ну так и имплицитно кастуй к инту/стрингу/енуму. switch это скушает.
А вот в case будь любезен записать константу.
Либо переходишь на C# 7.0 и пишешь что-то вроде такого (New C# 7 Features - Is Expression With Patterns And Switch...):
switch (currentModel) { case R33 r33 when (r33.ModelValue == "R33"): break; case R34 r34 when (r34.ModelValue == "R34"): break; }
А вот в case будь любезен записать константу.
-----
Ты просто внимания не обратил - оно и есть, по сути, константа. Только типа TModel, но без проблем совместимая с string/int.
То, что меня интересует - как это оформить...
case R33 r33 when (r33.ModelValue == "R33"):
скорее что-то вида:
case TModel currentModel when (currentModel == TModel.R33):
но что-то выглядит слишком сложно - можно и ифы аккуратно прописать...
Потому снова возвращаемся к простому вопросу - как описать константу некоего класса?
Ты просто внимания не обратил - оно и есть, по сути, константа. Только типа TModel, но без проблем совместимая с string/int.
Это константа только для тебя. Для всех остальных это ни секунды не константа.
Чтобы понять, что это не константа, просто скажи мне, как должен реагировать switch, если ты напишешь так:
public static Model R33 = new Model(_R33); public static Model Р34 = new Model(_R33);
?
Если бы это были бы константы, то при компилировании кода:
switch(currentModel) { case Model.R33: .... break; case Model.R34: .... break; }
ты должен был бы получить ошибку.
Я бы с удовольствием написал:
public const TModel R33 = _R33;но не понимаю (не знаю, не умейu) как определить класс ТМодел чтобы это было возможно.
В этом и есть вопрос.
A constant expression is an expression that can be fully evaluated at
compile time. Therefore, the only possible values for constants of
reference types are
string
and a null reference.
Так что ответ на твой вопрос - никак.
A constant expression is an expression that can be fully evaluated at compile time.
-----
Ты полагаешь, что Я этого не понимаю?
Понимаю и вполне отчетливо - не зря же Я упомянул помещающий синтаксис из плюсов - он как раз позволяет инициировать константы определяемых типов. Да, они полностью определяются при компиляции константированием обьекта.
Для решения проблемы в данном случае необходимо сделать две вещи:
- научится размещать в области хранения констант готовый к применению объект класса TModel. Можно ли его там разместить - не знаю - данные - точно можно, объекты стринг/инт - тоже. Т.е. в общем случае - можно. Вопрос - как.
- научить свитч понимать TModel, как инт/стринг. Практика синонимов - int == Int32 - и енумов в шарпе есть - т.е. проблема потенциально решаемая. Вопрос тот же - КАК?
Мне так кажется, что надо рыть вот тут:
https://docs.microsoft.com/en-us/dotnet/api/system.int32?v...
В плане - struct... и аттрибутов.