Мультиклассовая универсальная коллекция в C#

#java #c# #generics #wildcard

#java #c# #универсальные #подстановочный знак

Вопрос:

Мне нужна типобезопасная многотипная коллекция, например, карта, которая сопоставляет класс универсального тега Tag<T> с объектом типа T . На Java я бы написал что-то вроде этого:

 class ClassMap {
    private HashMap<Tag<?>,?> map = new HashMap<>();

    <T> void put(Tag<T> tag, T value){
        map.put(tag,value);
    }

    <T> get(Tag<T> tag){
        return (T) map.get(tag);
    }
}
 

Коллекция типобезопасна, т. Е. Приведение (T) всегда будет успешным, поскольку коллекция проверяет, соответствует ли класс тегу при вставке.

Но как это сделать в C #? Afaik, в C # нет подстановочных знаков, поэтому я не могу писать HashMap<Tag<?>,?> здесь. Как я могу сказать C #, что мне нужна общая карта, но я не могу точно указать ее параметры?

Ответ №1:

Вы пробовали это? Все классы C# являются производными от object .

РЕДАКТИРОВАТЬ: ссылка на класс объекта —

http://msdn.microsoft.com/en-us/library/system.object.aspx

Вы можете ввести любой объект для object ввода —

     class Tag<T>{

    }
    class ClassMap {
        private Dictionary<object, object> map = new Dictionary<object,object>();

        public void put<T>(Tag<T> tag, T value){
            map.Add(tag, value);
        }

        public T get<T>(Tag<T> tag){
            return (T)map[tag];
        }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            ClassMap v = new ClassMap();
            Tag<Int16> t = new Tag<short>();
            v.put<short>(t, 10);
            var tt = v.get<short>(t);
        }
    }
 

Информация об отладке —

введите описание изображения здесь

Комментарии:

1. Кажется, это делает то, что я хочу! Итак, справедливо ли это в целом: всякий раз, когда мне нужно поле класса, в котором были бы подстановочные знаки, если бы я написал его на Java, мне нужно заменить все типы подстановочных знаков на object (или другой не универсальный базовый класс) и отбросить их, как только они мне понадобятся?

2. Да, это будет работать в целом. Однако вам следует беспокоиться о производительности, приведение типов туда и object обратно — это тяжелая операция, и ее следует избегать, насколько это возможно.

3. Отлично, спасибо! Редактировать: Ну, если это такой удар по производительности, есть ли лучшие способы поддерживать коллекции, в которых могут быть смешаны различные типы? Я не вижу ни одного.

4. Боюсь, что нет, но есть изменения в архитектуре, которые вы можете сделать, чтобы вам не требовалось преобразование типов объектов. Вы можете попробовать другие шаблоны проектирования, такие как — IOC , шаблоны поиска служб и т. Д.