powered by simpleCommunicator - 2.0.57     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как сделать, чтобы доступ к атрибутам был как к членам класса?
25 сообщений из 63, страница 1 из 3
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145088
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Например, есть класс с атрибутами

Код: c#
1.
2.
3.
4.
5.
6.
[Display(Name = "Имя класса", Description = "Описание класса.")]
public class MyClass
{
	[Display(Name = "Имя свойства", Description = "Описание свойства.")]
	public int MyProperty { get; set; }
}



Хочу, чтобы доступ к значениям атрибутов был типа такого:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
string name = MyClass.Attributes.Display.Name;

MyClass myObject = new MyClass();

// далее или
string objectDescription = myObject.MyProperty.Attributes.Display.Description;

// или
string objectDescription = myObject.Attributes.MyProperty.Display.Description;



Т. е. состав коллекции Attributes должен зависеть от установленных атрибутов и значений их параметров.

Как сделать?

У меня соображение такое - для типов коллекция атрибутов должна быть статическим членом типа, а для экземпляров... не знаю какой. Для первого случае в моём коде получается какая-то обёртка над интовым свойством MyProperty, а для второго - просто коллеция Attributes, у которой атрибуты рассортированы в объекты с именами, совпадающими с именами свойств класса MyClass.
...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145095
Фотография LR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320,

"Как сделать... как к членам класса" - ну и сделайте "членами класса", что мешает? зачем вообще связываться с атрибутами, в чем необходимость?

ps. если бы у бабушки были яйца, она бы точно была дедушкой (с)
...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145105
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LRuser7320,

"Как сделать... как к членам класса" - ну и сделайте "членами класса", что мешает? зачем вообще связываться с атрибутами, в чем необходимость?

ps. если бы у бабушки были яйца, она бы точно была дедушкой (с)

Так я же объяснял (в других темах), что я не могу придумать унивресальную обёртку над интовыми (дабловыми и прочими) типами. Т. е. не могу придумать класс, который бы принимал объект любого типа и превращал бы его в объект нужного типа. Вот, пишу как члены класса, вместо атрибутов

double myValue;
string myValueName;
string myValueDescription;
double myValueMax;
double myValueMin;

Видите, жирным выделил - это у меня дабл. А я хочу, чтобы был любой тип. Мне придётся столько классов сделать, сколько типов я хочу использовать в такой конструкции. И если даже последние четыре свойства можно вынести в базовый класс, наследуемых классов всё равно будет по числу типов.
...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145110
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вместо дабла в выделенном поле должен стоять некий неопределённый тип. Тип должне определиться, когда я классу в, например, конструктор пошлю параметр (инт там, или дабл, или даже ссылочный тип). И после этого это значение уже должно во всех расчётах и в Интеллисенсе быть того типа, который я ему присвоил через параметр конструктора. Во как я хочу.
...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145115
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Nullable<T> не подходит, потому что он либо конкретный nullable (int?, нпример), либо неопределённый Nullable<T>, который надо при использовании в расчётах постоянно приводить к нужному типу.

object - то же самое - надо приводить постоянно (распаковка для типов значений).

C dynamic, мне кажется, тоже не прокатит, т. к. разве можно интенсивно использовать эти дайнэмики в математических расчётах? Я же знать не буду, что с чем использую и что где получаю. Да и Интеллисенс работать не будет.
...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145119
Фотография LR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320,

Вы бы сформулировали свою задачу на каком-то конкретном примере, а то, например мне, после нескольких Ваших тем, так и не понятно чего Вы в конце концов добиваетесь...(((
...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145129
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще, кто-нибудь использовал dynamic в расчётах, в которых все переменные - инты, даблы, флоаты и прочие - заменены на эти дайнэмики? Ну и как, нормально получалось? Я сейчас попробовал - можно и в индексы массива дайнэмики пихать, даже не приводя к типу int. Только такие расчёты чреваты ошибками - ведь проверки на типы во время редактирования кода и компиляции нет. Т. е. мне придётся смириться с этим, чтобы осуществить то, что я хочу?
...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145136
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LRuser7320,

Вы бы сформулировали свою задачу на каком-то конкретном примере, а то, например мне, после нескольких Ваших тем, так и не понятно чего Вы в конце концов добиваетесь...(((

У меня простая задача и я недоумеваю, почему ни у кого ничего подобного не возникало и никто не может нормально ответить.

Задача: есть настройки в виде чисел разных типов (даблы, инты и прочие). Эти настройки сгруппированы в группы настроек. Каждая группа - отдельный тип: Settings1, Settings2 и т. д. Все группы собраны под общим типом Settings.

Далее. К каждой настройке есть такие данные: название настройки (локализованное - берётся из ресурсов), описание найстроки (тоже локализованное), максимальное и минимальное допустимые значения и другие. К каждой группе настроек тоже есть название и описание.

Вроде, всё привычно? У каждого такое было? Я бы даже сказал, почти в каждом первом стандартном проекте, да?

Я спросил (давно уже было), как это всё легче организовать. Мне сказали, что все эти свойства настроек - это метаданные этих настроек, посему их надо в атрибуты. Я так и сделал. Настройки, значит, это у меня модель. Сами значения настроек используются в расчётах в модели, а их значения устанавливаются в интерфейсе через модель представления. Свойства же настроек (названия, описания) показывются тоже в модели представления. Значения и пределы значений настроек байндятся к контролам в представлениях.

Всё просто - каждый первый случай такой, да? Я НЕ ПОНИМАЮ - разве никто с этим не сталкивался? Почему нет стандартного способа решения?
...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145137
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторСвойства же настроек (названия, описания) показывются тоже в модели представления
Они тоже байндятся к контролам представления, только без возможности редактирования.
...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145143
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Итого - в модели есть атрибуты, а через модель представления в представлениях надо значения из этих атрибутов показать. Я пробовал с конвертерами - молучилось. Но слишком многословн - ближе к началу темы http://www.sql.ru/forum/actualthread.aspx?tid=1002838
и
http://www.sql.ru/forum/actualthread.aspx?tid=1000065

Потом вы уже, LR, подсказали, что проще хранить все значения атрибутов в коллекции и вызывать их своей нотацией. За что вам болшое спасибо - код упростился значительно и вся обслуга убралась в базовый класс, разгрузилась разметка.

Но и этого мне показалось мало. Почему, в конце-концов, я должен какие-то костыли придумывать?! Хочу, чтобы доступ к атрибутам был такой же удобный, как и к свойствам обычных объектов! Например, через точку.

Вот и вся история.
...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145149
Фотография LR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320Мне сказали, что все эти свойства настроек - это метаданные этих настроек, посему их надо в атрибуты. Я так и сделал. Настройки, значит, это у меня модель. Сами значения настроек используются в расчётах в модели, а их значения устанавливаются в интерфейсе через модель представления.
имхо, такие "метаданные" есть ничто иное как данные, посему их не надо в атрибуты...
...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145154
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Извиняюсь за неточность, и плохо, что здесь нельзя редактировать старые посты. Вобщем, код доступа к данным атрибутов в первом посте неправильный. На самом деле я хочу что-то типа такого:

Код: c#
1.
2.
3.
4.
5.
6.
// Get type attribute...
string className = MyClass.Attributes.Display.Name;

// Get member attribute...
string propertyDescription =
	MyClass.Properties.MyProperty.Attributes.Display.Name;



О как! Т. е. я хочу код, который автоматом заполнит статические поля-коллеции (или как там лучше организовать это) MyClass.Attributes и MyClass.Properties с нужными мне данными. При этом имена этих полей и имена вложенных в них полей, типа Display, Name и прочих, должны совпадать с составом свойств, атрибутов и свойств атрибутов для данного класса.
...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145156
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LRuser7320Мне сказали, что все эти свойства настроек - это метаданные этих настроек, посему их надо в атрибуты. Я так и сделал. Настройки, значит, это у меня модель. Сами значения настроек используются в расчётах в модели, а их значения устанавливаются в интерфейсе через модель представления.
имхо, такие "метаданные" есть ничто иное как данные, посему их не надо в атрибуты...
Если не в атрибуты, то вариант остаётся только в класс-обёртку. Или в базовый класс. Но тогда в любом случае в классе-обёртке должно быть поле, отвечающее за хранение самого значения настройки. А проблема в том, что это значение может быть одного из нескольких типов. Т. е. придётся столько обёрток делать, сколько типов настроек я хочу хранить. Так?
...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145160
Фотография LR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320Или в базовый класс.
чем плохо в базовый класс?
...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145163
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LRuser7320Или в базовый класс.
чем плохо в базовый класс?
А как САМО значение настройки хранить? Вот так?


Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
public class Base
{
	string myValueName;
	string myValueDescription;
	double myValueMax;
	double myValueMin;
}

public Setting1_of_Settings1 : Base
{
	double myValue;
}

public Setting2_of_Settings1 : Base
{
	int myValue;
}

public Setting1_of_Settings2 : Base
{
	bool myValue;
}

public Settings1 : Base
{
	Setting1_of_Settings1 setting1;
	Setting2_of_Settings1 setting2;
	Setting1_of_Settings2 setting3;
}
...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145164
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Только настроек у меня 50 штук. 50 штук классов - лучше с атрибутами маяться тогда уж.
...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145165
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, кстати, базовых классов тоже надо много - там максимум и минимум должны быть того же типа, что и само значение.
...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145185
Фотография LR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320,

для таких случаев можно использовать дженерики
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
    public class Setting<T>
    {
        public T MyValue { get; set; }
        public string MyValueName { get; set; }
        public string MyValueDescription { get; set; }
        public T MyValueMax { get; set; }
        public T MyValueMin { get; set; }
    }
...
... = new Setting<double> { MyValue = 0.11, MyValueMax = double.MaxValue, MyValueName = "test 11" };
... = new Setting<int> { MyValue = 12, MyValueMin = int.MinValue, MyValueName = "test 1-2" };
...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145238
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LRuser7320,

для таких случаев можно использовать дженерики
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
    public class Setting<T>
    {
        public T MyValue { get; set; }
        public string MyValueName { get; set; }
        public string MyValueDescription { get; set; }
        public T MyValueMax { get; set; }
        public T MyValueMin { get; set; }
    }
...
... = new Setting<double> { MyValue = 0.11, MyValueMax = double.MaxValue, MyValueName = "test 11" };
... = new Setting<int> { MyValue = 12, MyValueMin = int.MinValue, MyValueName = "test 1-2" };


А как использовать это в расчётах и как повлияет это на производительность?

Например,



Код: c#
1.
2.
3.
4.
5.
Setting<int> a = new Setting<int> { MyValue = 1, MyValueMax = int.MaxValue, MyValueName = "a" };
Setting<double> b = new Setting<double> { MyValue = 0.11, MyValueMax = double.MaxValue, MyValueName = "b" };
Setting<double> c = new Setting<double> { MyValue = 0.11, MyValueMax = double.MaxValue, MyValueName = "c" };

double x = (a.MyValue / Math.PI) + b.MyValue * Math.Pow(c.MyValue) / (array[a.MyValue] - array[a.MyValue - 1]);
...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145301
JohnSparrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если я правильно понял задачу топикстартера, то вот вариант решения:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;

namespace AttributedSettings
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("SettingsType1");
            Console.WriteLine("-------------");
            var x = new SettingsType1();
            foreach (var prop in x.GetType().GetProperties())
                foreach (var param in x.GetPropertyParameters(prop.Name))
                    Console.WriteLine("{0}.{1} = {2}", prop.Name, param, x.GetPropertyParameterValue(prop.Name, param));

            Console.WriteLine();
            Console.WriteLine("SettingsType2");
            Console.WriteLine("-------------");
            var y = new SettingsType2();
            foreach (var prop in y.GetType().GetProperties())
                foreach (var param in y.GetPropertyParameters(prop.Name))
                    Console.WriteLine("{0}.{1} = {2}", prop.Name, param, y.GetPropertyParameterValue(prop.Name, param));

            Console.ReadLine();
        }
    }
    
    public class SettingsType1 : SettingsBase
    {
        [Parameter("Name", "Test int property")]
        [Parameter("Description", "Some test property of type <int>")]
        [Parameter("DefaultValue", 100)]
        [Parameter("MinValue", 0)]
        [Parameter("MaxValue", 1000)]
        public int IntProperty { get; set; }

        [Parameter("Name", "Test string property")]
        [Parameter("DefaultValue", "Test")]
        public string StringProperty { get; set; }

        public SettingsType1()
        {
            IntProperty = 100;
            StringProperty = "Test";
        }
    }

    public class SettingsType2 : SettingsBase
    {
        [Parameter("Name", "Unique identifier")]
        [Parameter("DefaultValue", "63EFF92C-62B0-4B34-9EB7-F8303AA9B31F")]
        public Guid UID { get; set; }

        public SettingsType2()
        {
            UID = Guid.Parse("63EFF92C-62B0-4B34-9EB7-F8303AA9B31F");
        }
    }

    [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
    public class ParameterAttribute : Attribute
    {
        public string Name { get; set; }
        public object Value { get; set; }

        public ParameterAttribute(string name, object value)
        {
            Name = name;
            Value = value;
        }
    }

    public class SettingsBase
    {
        static SettingsBase()
        {
            _parameters = new Dictionary<Type, Dictionary<string, Dictionary<string, object>>>();
        }

        private static Dictionary<Type, Dictionary<string, Dictionary<string, object>>> _parameters;
        private Dictionary<Type, Dictionary<string, Dictionary<string, object>>> PropertiesParameters
        {
            get
            {
                if (!_parameters.ContainsKey(GetType()))
                {

                    var typePropertiesParameters = new Dictionary<string, Dictionary<string, object>>();

                    foreach (var property in GetType().GetProperties())
                    {
                        var attributes = property.GetCustomAttributes(typeof(ParameterAttribute), true);
                        if(attributes.Any())
                        {
                            var propertyParams = attributes.Cast<ParameterAttribute>().ToDictionary(attribute => attribute.Name, attribute => attribute.Value);
                            typePropertiesParameters.Add(property.Name, propertyParams);
                        }
                    }

                    _parameters.Add(GetType(), typePropertiesParameters);
                }

                return _parameters;
            }
        }

        public ReadOnlyCollection<string> GetPropertyParameters(string property)
        {
            if (!PropertiesParameters.ContainsKey(GetType()))
                throw new InvalidOperationException();

            if (!PropertiesParameters[GetType()].ContainsKey(property))
                throw new ArgumentException("property");

            return PropertiesParameters[GetType()][property].Keys.ToList().AsReadOnly();
        }

        public object GetPropertyParameterValue(string property, string name)
        {
            if (!PropertiesParameters.ContainsKey(GetType()))
                throw new InvalidOperationException();

            if (!PropertiesParameters[GetType()].ContainsKey(property))
                throw new ArgumentException("property");

            var propertyParams = PropertiesParameters[GetType()][property];

            if(!propertyParams.ContainsKey(name))
                throw new ArgumentException(null, "name");

            return propertyParams[name];
        }
    }
}


...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145429
Фотография LR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320Например,
ну и что?
...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145469
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LRuser7320Например,
ну и что?
Это как минимум многословно и неудобно набирать. По мне, так при расчётах, когда уже прошли все валидации, лучше создать иерархию подклассов без этой обвески в виде доп. параметров - оставить только значения. И с ними уже считать. Чтобы вместо Object.Subobject.Subobject.a было просто а. Но тогда уже с обвеской что мы имеем: сначала загоняем в обвеску - куча кода, а потом выводим из неё - куча кода. Получается, что кода не меньше, чем при атрибутах или конвертерах.

Меня атрибуты устраивали - удобный и компактный способ "приписать" данные к данным. Меня только не устраивает, как муторно к ним иметь доступ. Почему создатели фреймворка до сих пор не придумали удобный способ? И чтобы привязки работали. Вобщем, проблема только в том, что приходится самому кодить код-обслугу для такого доступа. И самодельный доступ получается какой-то "не нативный", а костыльный. А так я в атрибутах ничего плохого не вижу.
...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145470
user7320
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообще, непонятно, зачем помещать что-то в атрибуты, если достать что-то оттуда и привязаться к этому - лучше убиться?
...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145528
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user7320удобный и компактный способ "приписать" данные к данным.
исполизуй короткий термин - метаданные
...
Рейтинг: 0 / 0
Как сделать, чтобы доступ к атрибутам был как к членам класса?
    #38145557
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"Проблема" надумана и высосана из пальца.

.NET дает возможность использовать атрибуты, есть варианты:
использовать их

не использовать их
...
Рейтинг: 0 / 0
25 сообщений из 63, страница 1 из 3
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как сделать, чтобы доступ к атрибутам был как к членам класса?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]