Comments 24
Кат бы повыше…
0
Только синтаксис C# не позволит писать так в аттрибутах.
Как это не позволяет?!
public class Sensor
{
public SensorType Type { get; set; }
[Number(Type = SensorType.Temperature, Min = 200, Max = 600, Force = 273)]
[Number(Type = SensorType.Voltage, Min = -400, Max = 400, Force = 0)]
public decimal Value { get; set; }
}
public enum SensorType
{
Temperature,
Voltage
}
[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
class NumberAttribute : Attribute
{
public SensorType Type { get; set; }
public int Min { get; set; }
public int Max { get; set; }
public int Force { get; set; }
}
+2
От чего зависит свойство мы не сможем задать. Конкретно тут это “Type” — это свойство динамическое. Зависеть свойство может от любого другого поля в классе, а в другом классе вообще другие поля.А атрибут должен работать с разными классами. Это в JavaScript можно задавать то, что не объявлено. А тут вы не сможете в атрибуте прописать все поля от которых может зависить свойство. Вторая проблема, почему числа прописывается в строках — нельзя в атрибутах пользоваться decimal.
0
Вы недостаточно хорошо описали задачу, раз требуются дополнительные пояснения.
+2
Едва ли для аналоговых датчиков точность представления double перестанет Вас устраивать.
0
Хоть про decimal и написанно, что хорошо подходит для финансовых расчетов, для любых других подсчетов которые помещаются на дисплее датчика использовать необходимо только decimal. Пример:
Так вот в double сумма не будет равна 10, а decimal будет.
А вот что это за 0.001 может быть:
Примеров можно придумать много. Но все что можно или нужно представлять в десятичных дробях необходимо считать в decimal.
for (int i = 0; i < 10000; i++)
{
sumDouble += 0.001;
sumDecimal += 0.001m;
}
Так вот в double сумма не будет равна 10, а decimal будет.
А вот что это за 0.001 может быть:
- моментальное потребление в 1 литр, и мы считаем потребление за почти три часа(10000 сек) и 10 кубометров не получается
- это может быть шаг в поле принимающем значение от 0 до 10 в пользовательском интерфейсе, и при каком-то из нажатий стрелочки вверх вместо числа с тремя знаками после запятой, мы получим кучу девяток в хвосте
Примеров можно придумать много. Но все что можно или нужно представлять в десятичных дробях необходимо считать в decimal.
0
Только синтаксис C# не позволит писать так в аттрибутах.
Эммм… Кто Вам такое сказал? Именованные свойства называется.
0
«Головная боль при разработке и поддержке» — хорошее описание вашего финального велосипеда. У вас не возникало мысли, что где-то перемудрили, когда всё это изобретали? Задача верификации — не сложная, разжеванная и вполне решаема не write-only способом.
0
Вот в том то и дело, что с точки зрения того, кто будет пользоваться такой моделью, все очень просто. Поправил атрибут или повесил новый — и оно само работает. А вот как именно это работает наружу не вылезает. Ну как минимум за пол года никого не волновало. А вот предметная логика (то как зависят свойства друг от друга) собраны в одном месте и читабельны.
0
Забавно, что статья называется "Динамическое аспектно-ориентированное", но что именно?
+2
Для решаемой задачи идеально подходит язык Ada, ещё можно добавить использование SPARK (типы-подмножества, игры с точностью, контрактное программирование, доказательства правильности, ...).
В этой статье люди описывают создание своих велосипедов на C#. Ну ок, так тоже можно.
Вроде как с помощью Roslyn можно дополнить C# нужными вещами?
В этой статье люди описывают создание своих велосипедов на C#. Ну ок, так тоже можно.
Вроде как с помощью Roslyn можно дополнить C# нужными вещами?
+2
Можно написать конечный автомат, используя при этом шаблон проектирования «Состояние».
0
Мне кажется или все трудности автора происходят от недостаточной проработанности предметной области? Разработка самодостаточных типов данных обычно приводит к значительному упрощению алгоритмов.
Например, можно было ввести типы Voltage и Temperature, ограничения на значения ввести внутри них, а в класс Sensor добавить аргумент типа Sensor.
Например, можно было ввести типы Voltage и Temperature, ограничения на значения ввести внутри них, а в класс Sensor добавить аргумент типа Sensor.
0
В том то и дело, что предметная область не ложится на обычную обьектно-ориентированную модель.
Если ввести типы (Voltage и Temperature), то не плохо было бы еще унаследовать от них датчики конкретных производителей (например «Huaweo» и «Deck», где перые имеют подстройку, а вторые нет — Adjustment==0), потом унаследовать от них линейки датчиков(«Common» и «Flex» где вторые могут не просто измерять, а вычислять средние показатели за настроенный интервал — Interval!=0) — получатся классы типа VoltageDeckFlex в котором можно прописать конкретные модели с их возможными параметрами. При этом выяснится что у всех датчиков Flex по стандарту одинаковые ограничения для температурных и для напряжения, а классов VoltageFlex и TemperatureFlex нет и прописывать придется во всех классах (VoltageDeckFlex, VoltageHuaweoFlex, TemperatureDeckFlex, TemperatureHuaweoFlex)
С описанием же через атрибуты такой проблемы не возникнет
Вторая проблема — если пользователь заполнил настройку, а потом выяснил что модель у него другая — надо класс менять.
Если ввести типы (Voltage и Temperature), то не плохо было бы еще унаследовать от них датчики конкретных производителей (например «Huaweo» и «Deck», где перые имеют подстройку, а вторые нет — Adjustment==0), потом унаследовать от них линейки датчиков(«Common» и «Flex» где вторые могут не просто измерять, а вычислять средние показатели за настроенный интервал — Interval!=0) — получатся классы типа VoltageDeckFlex в котором можно прописать конкретные модели с их возможными параметрами. При этом выяснится что у всех датчиков Flex по стандарту одинаковые ограничения для температурных и для напряжения, а классов VoltageFlex и TemperatureFlex нет и прописывать придется во всех классах (VoltageDeckFlex, VoltageHuaweoFlex, TemperatureDeckFlex, TemperatureHuaweoFlex)
С описанием же через атрибуты такой проблемы не возникнет
public class Sensor
{
public virtual SensorType Type { get; set; }
public virtual CompanyType Company{ get; set; }
public virtual ModelType Model{ get; set; }
[Number("Company=Huaweo", "0")]
[Number("Company=Deck", "-10..10", Force = "0")]
public virtual decimal Adjustment{ get; set; }
[Number("", "0")]
[Number("Model=Flex", "0..100", Force = "0")]
public virtual decimal Interval{ get; set; }
[Number("Type=Temperature", "200..600")]
[Number("Type=Voltage", "-400..400")]
[Number("Type=Voltage;Company=Deck;Model=Flex", "-600..600")]
public virtual decimal Value { get; set; }
}
Вторая проблема — если пользователь заполнил настройку, а потом выяснил что модель у него другая — надо класс менять.
0
Вы хотите сказать, что параметры физических элементов хардкодятся, а не выносятся в настройки?..
0
Абсолютно согласен, могли бы, и реализовывались легко бы. Но в конкретно моем случае, это вещи которые нельзя выдавать пользователям. А если описывать во внутренних ресурсах, то не нашлось причин разделять класс и его ограничения.
Да и нагружать статью поставкой правил из конфигов, думаю лишнее — и так довольно тяжелая статья вышла
Да и нагружать статью поставкой правил из конфигов, думаю лишнее — и так довольно тяжелая статья вышла
0
В том то и дело, что предметная область не ложится на обычную обьектно-ориентированную модель.Предметная область не ложится на обычную обьектно-ориентированную модель для C#, если взять более мощный язык в области ООП, то будет легче.
0
А что, более вменяемо прямо совсем никак?
Ну, например
public sealed class Sensor {
public static Sensor Voltage() => new Sensor(SensorType.Voltage, -400, 400);
public static Sensor Temperature() => new Sensor(SensorType.Temperature, 200, 600);
Sensor(SensorType type, decimal min, decimal max) {
Type = type;
this.min = min;
this.max = max;
}
readonly decimal min;
readonly decimal max;
public SensorType Type { get; }
decimal value;
public decimal Value {
get { return value; }
set {
this.value = Max(Min(value, max), min);
}
}
}
0
Sign up to leave a comment.
Динамическое аспектно-ориентированное