Добавление родового объекта к универсальному списку в C#

Чтобы понять результат foldTree f g tree, вы можете использовать эту технику:

  • Запишите значение tree, используя конструкторы, например, в вашем примере мы имеем (Node (Node (Leaf 1) (Leaf 2)) (Leaf 4)).
  • Синтаксически заменить Leaf на f и Node на g. Для предыдущего примера мы получаем (g (g (f 1) (f 2)) (f 4)).
  • Используйте определения функций f и g для вычисления результата последнего выражения. Для примера, мы получаем ((+) ((+) ((*2) 1) ((*2) 2)) ((*2) 4)), который является ((+) ((+) (1*2) (2*2)) (4*2)), который является ((1*2) + (2*2)) + (4*2), который является (2+4)+8 = 14.

Обратите внимание, как мы заменяем Leaf унарный конструктор на f, унарную функцию, и Node, двоичный конструктор с g, двоичную функцию. Таким образом, у нас всегда есть правильное количество аргументов для наших функций. В общем, типы будут соответствовать просто отлично.

12
задан errcw 16 April 2009 в 00:36
поделиться

4 ответа

Я не думаю, что вы можете сделать это в C # ... вам придется добавить параметр типа в class:

class C<T> {
    void Method(SomeClass<T> obj) {
        list.Add(obj);
    }
    List<SomeClass<T>> list = new List<SomeClass<T>>();
}

Другой вариант - использовать интерфейс:

class C {

    void Method<T>(T obj)
         where T : ISomeClass {
        list.Add(obj);
    }
    List<ISomeClass> list = new List<ISomeClass>();
}
13
ответ дан 2 December 2019 в 07:22
поделиться

К сожалению, в C # 3.0 нет прямого эквивалента, так как обобщения являются инвариантными. Вы сможете сделать что-то подобное изящным образом, используя безопасную функцию co / contra-variance в C # 4.0. Чтобы обойти это, вы можете унаследовать SomeClass от неуниверсальной базы и создать вместо него List . Если каждый экземпляр класса должен содержать только один тип, вы можете сделать сам класс универсальным и установить там параметр типа.

2
ответ дан 2 December 2019 в 07:22
поделиться

Я ничего не знаю о Java ? , но я думаю, что нижеследующее наиболее точно сохраняет ваш существующий синтаксис, а также соответствует вашему описанию.

    class SomeClass<T>
    {
    }

    class C
    {
        void Add<T>(SomeClass<T> item)
        {
            Type type = typeof(SomeClass<T>);
            if (!list.ContainsKey(type))
                list[type] = new List<SomeClass<T>>();
            var l = (List<SomeClass<T>>)list[type];
            l.Add(item);
        }

        public void Method<T>(SomeClass<T> obj)
        {
            Add(obj);
        }
        readonly Dictionary<Type, object> list = new Dictionary<Type, object>();
    }

проверьте это следующим образом:

    class Program
    {
        static void Main(string[] args)
        {
            var c = new C();
            var sc1 = new SomeClass<int>();
            var sc2 = new SomeClass<String>();
            c.Method(sc1);
            c.Method(sc2);
            c.Method(sc1);
            c.Method(sc2);
        }
    }
2
ответ дан 2 December 2019 в 07:22
поделиться

Чтобы сделать то, что вы хотите, у вас есть два варианта.

Вы можете использовать List и обрабатывать объекты. Это не будет безопасным для типов и будет иметь проблемы с упаковкой / распаковкой для типов значений, но это будет работать.

Другой вариант - использовать общее ограничение для ограничения базовым классом или интерфейсом и использовать List .

4
ответ дан 2 December 2019 в 07:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: