如何转换IList<;T>;列出<;T>;在C#中,性能良好且简洁?

如何转换IList<;T>;列出<;T>;在C#中,性能良好且简洁?,c#,.net,performance,wcf,linq-to-entities,C#,.net,Performance,Wcf,Linq To Entities,尽管这些问题的答案中有一些信息,但它们并没有回答我的具体问题。我有一个类,它是一个包装列表。此类设计为通过WCF服务发送,并实现一些附加功能 [DataContract] public class DataContractList<T> : IList<T> { [DataMember] protected readonly List<T> InnerList; public DataContractList() {

尽管这些问题的答案中有一些信息,但它们并没有回答我的具体问题。我有一个类,它是一个包装列表。此类设计为通过WCF服务发送,并实现一些附加功能

[DataContract]
public class DataContractList<T> : IList<T>
{
    [DataMember]
    protected readonly List<T> InnerList;

    public DataContractList()
    {
        InnerList = new List<T>();
    }

    public DataContractList(IList<T> items)
    {
        InnerList = items as List<T> ?? items.ToList(); //Question is about this line.
    }
}
[DataContract]
公共类DataContractList:IList
{
[数据成员]
受保护的只读列表InnerList;
公共数据契约列表()
{
InnerList=新列表();
}
公共数据合同清单(IList项目)
{
InnerList=items as List??items.ToList();//问题是关于此行的。
}
}

因此,有一个构造函数接受
IList
接口(以鼓励编程到接口)。我需要将这个
IList
接口转换为
List
类。我可以使用
.ToList()
扩展方法,通过将IEnumerable“this”参数传递给它的构造函数,在内部创建
列表的新实例(请参阅)。泛型
List
构造函数只是在这个可枚举项中迭代。因此,如果不需要,我希望阻止此迭代(如果内部项参数已经是
列表
)。那么,这是一种最佳的方式(在性能和可读性方面):
InnerList=items as List??items.ToList()?如果没有,请详细说明更好的方法和原因。

我的意思是,如果你继承了
IList
,然后强制使用
列表
,这就违背了目的,不是吗

使用接口的想法是支持只有共享功能才重要的不同类

在您的情况下,您的
DataContractList
类接受任何实现
IList
的类,但是如果我创建了一个实现
IList
但无法转换为
List
的类,我会得到一个运行时错误,不是吗

如果您的
DataContractList
类只能支持该接口的实现,我建议您从
List
继承

或者,如果您的
DataContractList
类能够真正支持
IList
的任何实现,则将其更改为:

[DataContract]
public class DataContractList<T> : IList<T>
{
    [DataMember]
    protected readonly IList<T> InnerList;

    public DataContractList()
    {
        InnerList = new List<T>();
    }

    public DataContractList(IList<T> items)
    {
        InnerList = items;
    }
}
[DataContract]
公共类DataContractList:IList
{
[数据成员]
受保护的只读IList内部列表;
公共数据契约列表()
{
InnerList=新列表();
}
公共数据合同清单(IList项目)
{
InnerList=项目;
}
}

试图避免重复列表是一个好的意图,但是还有更多的要考虑。

您已经保护了
InnerList
属性,使其不受公共访问,如果您只是将列表分配给该属性,那么这样做是没有意义的。如果我向构造函数发送一个列表并保留对该列表的引用,那么我就有了对该类内部使用的列表的引用:

List<sting> list = new List<string>();
var dc = new DataContractList(list);

// now I can manipulate the internal list:
list.Add("Woaaah! Where did that come from?");
List List=新列表();
var dc=新数据合同清单(清单);
//现在我可以操作内部列表:
添加(“哇!那是从哪里来的?”);
要使内部列表保持内部状态,即使输入是列表,也始终要创建一个新列表:

public DataContractList(IList<T> items)
{
    InnerList = new List<T>(items);
}
公共数据契约列表(IList项)
{
InnerList=新列表(项目);
}

您注意到WCF默认序列化不适用于任意的
IList
实现。那很好

然后,您决定通过强制使用
List
来解决这个问题。那不太好

如果默认序列化不符合您的要求,请不要使用它。使用自定义序列化。如果您知道这是您想要做的,即使内部容器不知道,您也可以让您的类逐项序列化


为了回答您可能的后续问题:快速搜索显示了如何在堆栈溢出上执行此操作的基本方法:

只需完成Guffa的回答。正如你提到的,使用

InnerList = new List<T>(items);
基本上是一样的,所以从可读性的角度来看,我更喜欢后者

然而,以下情况

泛型列表构造函数只是遍历这个可枚举的


不是真的,正如您在这里看到的,当参数的类型为
List
时,反过来使用。简而言之,您不应该担心性能。

不要从列表或IList继承。创建一个将IList作为属性的新类。为什么不使用受保护的只读IList InnerListInnerList=项目作为列表有什么问题??items.ToList()首先?一个问题可能是传递
列表
与传递其他
IList
的语义。在第一种情况下,您将以对基础列表的引用结束,该列表将在您更改该对象时看到更新。在另一种情况下,您将得到一个列表的副本,该副本不会随着基础IList的更改而更改。@Vova转换是一个非常便宜的操作。它是一个WCF数据协定-它必须使用具体类型进行序列化IIRC。我试图从列表继承自定义列表,但这又是WCF的一个问题(我不记得是哪个问题)。如果IList的某些实现无法转换为List,那么它将转到.ToList()扩展,不是吗?为什么我会在这里出现运行时错误?而且WCF无法为接口成员生成WSDL。@Lucastrezesniewski是的,这是显而易见的,这就是为什么我建议从
列表
继承的原因。但是我试图让我的答案更一般化,什么时候使用接口,什么时候使用具体的类。@Vova我必须先看看你从
List
继承时遇到的问题,然后我才能帮助你。至于您关于
.ToList()
的问题,归根结底是如何使用传递的实例。就像我说的,如果您只使用接口中由定义的公共属性/方法,那么您当然可以。但是如果你尝试使用一些属性/met
InnerList = items.ToList();