Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 泛型类列表的泛型方法_C#_List_Class_Generics_Methods - Fatal编程技术网

C# 泛型类列表的泛型方法

C# 泛型类列表的泛型方法,c#,list,class,generics,methods,C#,List,Class,Generics,Methods,我有问题。 例如,考虑这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> { }

我有问题。 例如,考虑这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
{
}
公共抽象父容器,其中T:Parentfoo
{
公开名单愚人;
}
//让有许多不同类型的子容器。
公共类ChildContainer:ParentContainer
{
}
公共抽象类ParentFoo
{
公共字符串名称;
}
公共类ChildFoo:ParentFoo
{
}
如何编写一个方法来接受任意子容器的列表作为参数, 你对他们的傻瓜们采取了什么行动? 有可能吗

另外解释一下,ParentContainer有很多不同的孩子, 每个都有一个foo的不同子级的列表

public class ChildContainerB : ParentContainer<ChildFooB>{}
public class ChildContainerC : ParentCOntainer<ChildFooC>{}
...

public class ChildFooB : ParentFoo;
public class ChildFooC : ParentFoo;
公共类ChildContainerB:ParentContainer{}
公共类ChildContainer:ParentCOntainer{}
...
公共类ChildFooB:ParentFoo;
公共类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);
    }
}
//X表示它可以是任意子容器
公共作废方法(列表)
{
foreach(列表中的ChildContainerX)
{
打印(x.doulist.Last().name);
}
}

除非我误解了这个问题,否则你想要这样的东西

public void DoStuffWith<T>(List<ParentContainer<T>> containers) where T : Parentfoo
{
     //TODO: implement
}
public void dostufwith(列出容器),其中T:Parentfoo
{
//TODO:实现
}
这将适用于类型为

List<ParentContainer<ParentFoo>>
List<ParentContainer<ChildFoo>>
列表
列表
何处ChildFoo:ParentFoo

并解决了“
List
未实现
IEnumerable
”的问题,我怀疑这就是您正在看到的编译器

更进一步,比如

public void DoStuffWith<ContainerT,ElementT>(List<ContainerT<ElementT>> containers) 
  where ContainerT : ParentContainer 
  where ElementT : Parentfoo
{
     //TODO: implement
}
public void dostufwith(列出容器)
其中ContainerT:ParentContainer
where元素t:Parentfoo
{
//TODO:实现
}
。。。可能会使问题变得过于复杂,但我怀疑这正是你想要实现的

在这一点上,我会质疑你的数据结构,并给他们一些共同的家长,例如

public class ParentContainer<T> : IEnumerable<T> { ... }
public class ChildContainer<T> : ParentContainer<T>, IEnumerable<T> { ... } 
公共类ParentContainer:IEnumerable{…}
公共类ChildContainer:ParentContainer,IEnumerable{…}
既然这两个都实现了IEnumerable,您现在可以执行

public void DoStuffWith<T>(IEnumerable<T> containers) where T : ParentFoo
{
     //TODO: implement
}
public void dostufwith(IEnumerable containers),其中T:ParentFoo
{
//TODO:实现
}

这就完全避免了与集合类型相关的需要。

因此您所要求的是不可能的,因为您需要为
列表提供具体的类型。不过,还有一些变通办法

  • 使用
    List
    。这显然不是很好,因为这意味着您完全丢失了类型检查,并且可能会导致列表中添加任何内容。因此,出于这个原因,我不推荐这种方法

  • 使
    ParentContainer
    实现标记接口。例如:

    public interface IParentContainer
    {
    }
    
    public abstract class ParentContainer<T> : IParentContainer
        where T: ParentFoo
    {
        //snip
    }
    
    公共接口IParentContainer
    {
    }
    公共抽象类ParentContainer:IParentContainer
    其中T:ParentFoo
    {
    //剪断
    }
    
    现在,您可以获得如下列表:

    var containers = new List<IParentContainer>
    {
        new ChildContainer(),
        new ChildContainer2()
    };
    
    var容器=新列表
    {
    新的子容器(),
    新的ChildContainer2()
    };
    
  • 类程序
    {
    静态void Main(字符串[]参数)
    {
    列表ca=新列表();
    ProcessContainers处理器=新的ProcessContainers();
    ca.Add(new ChildContainerA{doulist=new List()});
    ca.Add(new ChildContainerA{doulist=new List()});
    ca.Add(new ChildContainerA{doulist=new List()});
    ca.Add(新的ChildContainerB{doulist=new List()});
    处理器进程(ca);
    }
    }
    公共抽象类ParentContainer,其中T:ParentFoo
    {
    公开名单愚人;
    }
    //让有许多不同类型的子容器。
    公共类ChildContainerA:ParentContainer
    {
    }
    公共类ChildContainerB:ParentContainer
    {
    }
    公共类ProcessContainers
    {
    公共作废进程(列出子容器),其中T:ParentFoo
    {
    foreach(子容器中的变量项)
    {
    foreach(item.doulist中的变量foo)
    {
    foo.Porcess();
    }
    }
    }
    }
    公共抽象类ParentFoo
    {
    公共字符串名称;
    公共抽象无效过程();
    }
    公共类ChildFoo:ParentFoo
    {
    公共覆盖无效进程()
    {
    //做一些处理
    }
    }
    
    所有
    ChildContainer
    实例都会有一个
    ChildFoo
    的列表,所以是的,这是可能的,但我怀疑这不是您想要的。你能再解释一下吗?你能至少把你后编译的示例代码做出来吗?什么是
    foo
    ,你的意思是
    ParentFoo
    ?还有,当你说任意子容器的列表时,你真的是说从ParentContainer继承的任何对象的列表吗?@DavidG是的,这就是我的意思。@giulioccin是的,对不起。我已经更正了我的示例代码!谢谢你的提示!我不是在要求投票。。。只是想结束这个问题。我的错,注意到了!我编辑了我的答案,以反映问题的变化。@War这正是我想要的。但你的例子并不完全正确。因为
    其中T:ChildContainer
    仅用于一个特定的ChildContainer新版本是否有帮助?@war但我有一个ChildContainer列表。。。我无法将
    List
    传递给methodProcessContainers类,该类可用于处理许多包含foo列表的容器。希望这会有帮助希望这会有帮助
    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
        }
    }