Чтобы понять результат 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
, двоичную функцию. Таким образом, у нас всегда есть правильное количество аргументов для наших функций. В общем, типы будут соответствовать просто отлично.
Я не думаю, что вы можете сделать это в 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>();
}
К сожалению, в C # 3.0 нет прямого эквивалента, так как обобщения являются инвариантными.
Вы сможете сделать что-то подобное изящным образом, используя безопасную функцию co / contra-variance в C # 4.0.
Чтобы обойти это, вы можете унаследовать SomeClass
от неуниверсальной базы и создать вместо него List
.
Если каждый экземпляр класса должен содержать только один тип, вы можете сделать сам класс универсальным и установить там параметр типа.
Я ничего не знаю о 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);
}
}
Чтобы сделать то, что вы хотите, у вас есть два варианта.
Вы можете использовать List
Другой вариант - использовать общее ограничение для ограничения базовым классом или интерфейсом и использовать List