创建抽象基类的数组或列表或子集合

时间:2017-03-08 03:33:23

标签: c# arrays strong-typing

试图帮助这里的朋友。我不是Microsoft程序员。

public abstract class Foo {}
public class Bar : Foo {}
public class Baz : Foo {}

这似乎工作得很好,然后在另一个类中,他可以像这样实例化BarBaz的数组

public class MyClass {
  Bar[] Bars = new Bar[] { new Bar[] { new Bar(), new Bar() } }
  Baz[] Bazs = new Baz[] { new Baz[] { new Baz(), new Baz() } }
}

问题是他是否想拥有一个返回FoosBars的访问者,他是如何做到的?

public class MyClass {
  Bar[] Bars = new Bar[] { new Bar[] { new Bar(), new Bar() } }
  Baz[] Bazs = new Baz[] { new Baz[] { new Baz(), new Baz() } }
  public IEnumerable<Foo> GetFoos() {
    // No go.
    return [ Bars, Bazs ];

    // Also No go.
    List<Foo> test = new List<Foo> { Bars, Bazs };
    return test;
  }
}

我认为Microsoft通常使用接口来实现它,但是他的赋值要求使用抽象基类。有没有办法返回抽象基类的List或子数组?

3 个答案:

答案 0 :(得分:0)

在这两种情况下,您都无法创建新的Foo()&#39;作为&#39; Foo&#39;是一个抽象类。您可以创建Bar和Baz的对象并返回Foo数组。看看以下答案是否有帮助。

    public class MyClass
    {
        Foo[] Foos1 = new Foo[] { new Bar(), new Bar() };
        Foo[] Foos2 = new Foo[] { new Baz(), new Baz() };

        // OR use as below

        /*
        Foo[] Foos1 = new Bar[] { new Bar(), new Bar() };
        Foo[] Foos2 = new Baz[] { new Baz(), new Baz() };
        */

        public IEnumerable<Foo> GetFoos1()
        {
            // Works.
            return Foos1;
        }

        public IEnumerable<Foo> GetFoos2()
        {
            // Works
            List<Foo> test = new List<Foo>();
            test.AddRange(Foos2);
            return test;
        }
    }

答案 1 :(得分:0)

为了将另一个IEnumerable&T添加到列表中,您必须使用&#34; AddRange&#34;像:

List<Foo> test = new List<Foo>();
test.AddRange(Foos);
test.AddRange(Bars);

return test;

您还可以使用List构造函数重载,以便将现有的IEnumerable&T添加到您的列表中:

List<Foo> test = new List<Foo>(Foos);
test.AddRange(Bars);

return test;

答案 2 :(得分:0)

无需复制数组。以下代码将生成IEnumerable<Foo>,它始终反映数组的当前内容,并且不消耗任何大量内存:

public class MyClass
{
    private Bar[] Bars = new Bar[] {new Bar(), new Bar()};
    private Baz[] Bazs = new Baz[] {new Baz(), new Baz()};

    public IEnumerable<Foo> GetFoos()
    {
        // Cast Bars as an Enumerable<Foo>, then append Bazs 
        // (no need to explicitly cast Bazs)
        return Bars.AsEnumerable<Foo>().Concat(Bazs);

        // or

        // Create an empty Enumerable<Foo>, then append Bazs and Bars
        return Enumerable.Empty<Foo>().Concat(Bars).Concat(Bazs);
    }
}

这里GetFoos()返回的对象只是对两个原始数组的引用。每当代码枚举此IEnumerable时,它将隐式访问两个原始数组。因此,如果在调用GetFoos()之后,但在使用结果表单GetFoos()之前,有人用NULL替换Bars的每个项,那么调用GetFoos()的代码将只看到一堆NULL。

如果您不想在更改原始数组的内容时更改返回的IEnumerable的内容,则需要创建一个副本,如下所示:

public IEnumerable<Foo> GetFoos()
{
    return Enumerable.Empty<Foo>().Concat(Bars.ToArray()).Concat(Bazs.ToArray());
}