Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.79/19: Рейтинг темы: голосов - 19, средняя оценка - 4.79
1 / 1 / 0
Регистрация: 05.02.2011
Сообщений: 25

Обобщенные типы в обобщенных коллекциях

26.03.2012, 12:24. Показов 3638. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Делаю векторный редактор. Надо реализовать в нем панель свойств. Хочу сделать ее на основе редакторов типов, чтобы когда выделяется фигура, панель свойств брала все ее свойства, получала их типы и в зависимости от типа выбирала необходимый редактор. Редакторы хочу хранить в отдельном классе, например так:
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
using System;
using System.Collections.Generic;
 
namespace Lab3.Model.Editors
{
    public class EditorRegistry
    {
        private static Dictionary<Type, Editor> editors;
 
        static EditorRegistry()
        {
            editors = new Dictionary<Type, Editor>();
            editors.Add(typeof(int), new IntegerEditor());
            editors.Add(typeof(double), new DoubleEditor());
            editors.Add(typeof(bool), new BooleanEditor());
            editors.Add(typeof(string), new StringEditor()); //и т.д.
        }
 
        public static Editor GetEditor(Type type)
        {
            Editor e;
            editors.TryGetValue(type, out e);
        }
    }
}
Здесь Editor должен быть интерфейсом, а IntegerEditor, DoubleEditor и т.д. его реализациями для соотв. типов.
Хотел сделать Editor параметризованным:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
using System;
using System.Windows.Forms;
 
namespace Lab3.Model.Editors
{
    public interface Editor<T>
    {
        EditorModel<T> GetModel();
        T GetValue();
        void SetValue(T value);
        Control GetComponent();
    }
}
сделать ему абстрактную реализацию:
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
using System;
using System.Windows.Forms;
 
namespace Lab3.Model.Editors
{
    public abstract class AbstractEditor<T> : Editor<T>
    {
        protected EditorModel<T> model = new DefaultEditorModel<T>();
 
        public EditorModel<T> GetModel()
        {
            return model;
        }
 
        public T GetValue()
        {
            return model.GetValue();
        }
 
        public void SetValue(T value)
        {
            model.SetValue(value);
        }
 
        public abstract Control GetComponent();
    }
}
и допустим реализация редактора для типа int:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using System;
using System.Windows.Forms;
 
namespace Lab3.Model.Editors
{
    public class IntegerEditor : AbstractEditor<int>
    {
        private TextBox editor = new TextBox();
 
        public override Control GetComponent()
        {
            return TextBox;
        }
    }
}
Но в таком случае я не могу хранить его реализации для различных типов в Dictionary<Type, Editor>, т.к. при создании нужно указывать тип-параметр для Editor сразу (типа Dictionary<Type, Editor<int>>). можно конечно сделать это через switch, но хотелось бы через коллекции. Подскажите что-нибудь умное для этого случая?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
26.03.2012, 12:24
Ответы с готовыми решениями:

Обобщенные типы
У меня есть абстрактный класс Appearance&lt;T&gt;. От него наследуются другие классы: Appearance2D&lt;T1&gt;, Appearance2D&lt;T2&gt; и т. д. ...

Контрвариация обобщенных интерфейсов
Насколько я понимаю, если определен контрвариационный обобщенный интерфейс, то метод, чей параметр помечен как in, должен принимать либо...

Обобщенные типы
Я бы хотел написать подобную конструкцию: public class test&lt;T&gt; { public static T func(T t){return t*t;} } где T - может быть...

7
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
26.03.2012, 12:56
Когда вы вызовете GetEditor из вашего хранилища, параметр generic не имеет смысла, так как вызывающий тип не знает его и не должен его знать. В таком случае нужно сделать ваш generic Editor наследником другого не обобщенного Editor-a.
Вот пример http://stackoverflow.com/q/3215402/272742
В этом случае не понятно тогда что будет делать вызывающий код и вся идея обобщений в вашем случае потеряет смысл, так как он не будет знать какой тип например будет возвращать метод GetValue.

Надо отказаться от конструкций вида typeof(int) или от дженериков.
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
26.03.2012, 12:59
Я бы отказался от идеи с генериками, так как в предложенной вами архитектуре простым способом их не реализовать.
Сделайте что-то вроде уже существующей компонентной модели для редактирования различных типов, имеющейся в .NET.
Начать можете с изучения класса UITypeEditor и сделать что-то подобное ему. Уже от этого абстрактного редактора будут наследоваться другие, которые изменяют значение нужным им образом.
0
1 / 1 / 0
Регистрация: 05.02.2011
Сообщений: 25
26.03.2012, 13:04  [ТС]
Ну вот, сам нашел решение. Сделал реестр редакторов таким образом:
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
using System;
using System.Collections.Generic;
 
namespace Lab3.Model.Editors
{
    public class EditorRegistry
    {
        private static Dictionary<Type, object> editors = new Dictionary<Type, object>();
 
        static EditorRegistry()
        {
            Register<int>(new IntegerEditor());
        }
 
        public static Editor<T> GetEditor<T>(T type) where T : Type
        {
            Object o;
            editors.TryGetValue(type, out o);
            Editor<T> e = null;
            if (o != null)
            {
                e = (Editor<T>)o;
            }
            return e;
        }
 
        private static void Register<T>(Editor<T> editor)
        {
            Type t = typeof(T);
            editors.Add(t, editor);
        }
    }
}
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
26.03.2012, 13:12
В вашей реализации теряется вся суть generic-ов:
1) хранение object-ов вместо точного безопасного типа.
2) Вот в этом методе
C#
1
public static Editor<T> GetEditor<T>(T type) where T : Type
Вы уже сделали метод параметризованным как generic, зачем в таком случае вам еще и параметр T type ?

Только создали себе трудностей, а потом преодолели эти трудности с помощью костылей.
0
1 / 1 / 0
Регистрация: 05.02.2011
Сообщений: 25
26.03.2012, 20:01  [ТС]
Цитата Сообщение от turbanoff Посмотреть сообщение
Вы уже сделали метод параметризованным как generic, зачем в таком случае вам еще и параметр T type ?
Это точно. Незаметил

А что касатеся :
Цитата Сообщение от turbanoff Посмотреть сообщение
1) хранение object-ов вместо точного безопасного типа.
У меня ведь никакой другой класс не имеет доступа к этому списку редакторов, а этот класс знает, что у него в списке хранятся реализации Editor<T>, пусть и в виде object-ов. Плюс метод Register<T>(Editor<T> editor) не позволит записать в этот список ничего кроме реализации Editor<T>
0
Эксперт Java
 Аватар для turbanoff
4094 / 3828 / 745
Регистрация: 18.05.2010
Сообщений: 9,331
Записей в блоге: 12
27.03.2012, 08:30
Ладно, вы написали generic класс, давайте подумаем как вы его будете использовать, ведь вам надо как-то обобщить все Editor-ы предоставив общий интерфейс управления ими.
Вызываете так:
C#
1
2
Editor<int> ieditor = EditorRegistry.GetEditor<int>(typeof(int));
Editor<double> deditor = EditorRegistry.GetEditor<double>(typeof(double));
Вот что дальше с этими Editor-ами делать - не понятно, ведь никакого общего метода, у них нет, в коллекцию их не сложить (или опять использовать не безопасные коллекции). И вообще смысла в них я не вижу. Просто две разные переменные, с разными типами и разным интерфейсом.

К чему это я, нужно делать общий, не generic-овский интерфейс, от которого будет наследоваться обобщенный, тогда много проблем решатся сами собой.
0
1 / 1 / 0
Регистрация: 05.02.2011
Сообщений: 25
27.03.2012, 09:42  [ТС]
turbanoff

Да, вы правы. Здесь еще проблема в том, что я не знаю заранее тип свойства фигуры. Он станет известным только во время выполнения, и то я смогу получить только объект типа Type, а такая реализация не позволяет получить редактор по известному Type. В общем буду пробовать реализовать через не generic интерфейс.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
27.03.2012, 09:42
Помогаю со студенческими работами здесь

Нумераторы в коллекциях
Здравствуйте нашел в сети такой пример для обьяснения нумераторов в коллекциях. class Program { static void Main() ...

Слить совпадающие элементы в разных коллекциях
public class SalesOrder { public string Name { get; set; } public double Price { get; set; } public int Quantity {...

Замена строк в коллекциях по одинаковому вхождению
Доброго времени суток форумчанам. Существует нетривиальная задача. Есть две коллекции в одной существуют строки типа 123 1, 1234 2 - во...

Копирование обобщенных коллекци
Как правильно копировать обобщенные коллекции ? Например: class SimpleClass { public int Number; ...

Сравнение обобщенных переменных
Доброго времени суток форумчане. Есть класс: public class A&lt;T&gt; { public T Inside { get; set; } /// &lt;summary&gt; ///...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru