将IEnumerable <t>转换为包装类

时间:2018-01-08 17:28:10

标签: c# generics collections casting

我有一个实际上是IEnumerable包装器的类:

public class MyThings : IEnumerable<Thing>
{

}

我像这样创建一个Thing的可枚举:

var things = new [] {new Thing (), new Thing()};

由此,我想创建一个MyThings的实例 - 类似于以下内容:

var myThings = things as MyThings;

这当然行不通。

一种解决方案是将Add方法添加到MyThings和内部List<Thing>

public class MyThings : IEnumerable<Thing>
{
    private readonly List<Thing> list = new List<Thing>();

    public MyThings this[int index]
    {
        get { return list[index]; }
        set { list.Insert(index, value); }
    }

    public IEnumerator<Thing> GetEnumerator()
    {
        return list.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public void Add(Thing thing)
    {
        list.Add(thing);
    }
}

这样,我可以通过自动初始化创建它,如:

var things = new MyThings {new Thing (), new Thing()};

但这似乎并不优雅。

有铸造方法吗?

修改 本着“你为什么要这样做”的精神,

我们可以将自定义JsonConverter应用于整个类型(MyThings

1 个答案:

答案 0 :(得分:1)

一个数组,来自:

var things = new [] {new Thing (), new Thing()};

是一个数组(Thing[])。它总是一个数组,除了一个数组。它不会是MyThings

现在,您可以添加一个转换运算符,允许在它们之间进行显式或隐式转换,但很可能您正在做的所有事情都是添加不必要的中间数组分配。坦率地说,我认为你的Add加法以及集合初始化语法是最好的选择。

但是,您也可以添加:

public static implicit operator MyThings(Thing[] things) {
    // your logic here
}

然后这可行:

var arr = new[] { new Thing(), new Thing() };
MyThings things = arr;

或者如果您使用explicit代替implicit,则:

var arr = new[] { new Thing(), new Thing() };
MyThings things = (MyThings)arr;

如果MyThings 只是包装数组,那么运算符方法可能是一个好主意,并且您将把它存储在字段中而不重复它,即如果您的实现基本上是:

this._things = things;