我有问题。 例如,考虑这4个类。
public abstract ParentContainer<T> where T: Parentfoo
{
public List<T> fooList;
}
//Let there be many different ChildContainers with different types.
public class ChildContainer : ParentContainer<ChildFoo>
{
}
public abstract class ParentFoo
{
public string name;
}
public class ChildFoo : ParentFoo
{
}
如何编写一个接受任意ChildContainers的List作为参数的方法, 哪些操作在他们的fooLists上? 它甚至可能吗?
附加说明,ParentContainer有许多不同的子节点, 每个都有一个foo的不同孩子的列表。
public class ChildContainerB : ParentContainer<ChildFooB>{}
public class ChildContainerC : ParentCOntainer<ChildFooC>{}
...
public class ChildFooB : ParentFoo;
public class ChildFooC : ParentFoo;
然后我需要一个像这样的方法
//X means it can be any arbitrary ChildContainer
public void method(List<ChilContainerX> list)
{
foreach(ChildContainerX x in list)
{
print(x.fooList.Last().name);
}
}
答案 0 :(得分:1)
所以你问的是不可能的,因为你需要List<>
的具体类型。但是有一些解决方法。
使用List<object>
。这显然不是很好,因为这意味着你完全失去了类型检查,最终可能会添加到列表中的任何内容。因此,我不推荐这种方法。
让ParentContainer<>
实现标记界面。例如:
public interface IParentContainer
{
}
public abstract class ParentContainer<T> : IParentContainer
where T: ParentFoo
{
//snip
}
现在你可以这样列出:
var containers = new List<IParentContainer>
{
new ChildContainer(),
new ChildContainer2()
};
答案 1 :(得分:0)
除非我误解了这个问题,否则你需要这样的东西......
public void DoStuffWith<T>(List<ParentContainer<T>> containers) where T : Parentfoo
{
//TODO: implement
}
这适用于类型为...的对象
List<ParentContainer<ParentFoo>>
List<ParentContainer<ChildFoo>>
其中ChildFoo:ParentFoo
并解决了问题&#34; List<ParentContainer<ParentFoo>>
没有实现IEnumerable<ParentContainer<ChuldFoo>>
&#34;我怀疑是你看到的编译器。
更进一步,比如......
public void DoStuffWith<ContainerT,ElementT>(List<ContainerT<ElementT>> containers)
where ContainerT : ParentContainer
where ElementT : Parentfoo
{
//TODO: implement
}
...可能使问题复杂化,但我怀疑你正在努力实现的目标。
此时我会质疑你拥有的数据结构,并给他们一些共同的父母,例如......
public class ParentContainer<T> : IEnumerable<T> { ... }
public class ChildContainer<T> : ParentContainer<T>, IEnumerable<T> { ... }
由于两者都实现IEnumerable,你现在可以做...
public void DoStuffWith<T>(IEnumerable<T> containers) where T : ParentFoo
{
//TODO: implement
}
这样就可以避免需要关注集合类型。
答案 2 :(得分:0)
class Program
{
static void Main(string[] args)
{
List<ParentContainer<ChildFoo>> ca = new List<ParentContainer<ChildFoo>>();
ProcessContainers processor = new ProcessContainers();
ca.Add(new ChildContainerA { fooList = new List<ChildFoo>() });
ca.Add(new ChildContainerA { fooList = new List<ChildFoo>() });
ca.Add(new ChildContainerA { fooList = new List<ChildFoo>() });
ca.Add(new ChildContainerB { fooList = new List<ChildFoo>() });
processor.Process(ca);
}
}
public abstract class ParentContainer<T> where T: ParentFoo
{
public List<T> fooList;
}
//Let there be many different ChildContainers with different types.
public class ChildContainerA : ParentContainer<ChildFoo>
{
}
public class ChildContainerB : ParentContainer<ChildFoo>
{
}
public class ProcessContainers
{
public void Process<T>(List<ParentContainer<T>> childContainers) where T : ParentFoo
{
foreach(var item in childContainers)
{
foreach(var foo in item.fooList)
{
foo.Porcess();
}
}
}
}
public abstract class ParentFoo
{
public string name;
public abstract void Porcess();
}
public class ChildFoo : ParentFoo
{
public override void Porcess()
{
//Do some processing
}
}