如何转换IList<;T>;列出<;T>;在C#中,性能良好且简洁?
尽管这些问题的答案中有一些信息,但它们并没有回答我的具体问题。我有一个类,它是一个包装列表。此类设计为通过WCF服务发送,并实现一些附加功能如何转换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() {
[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 InnerList代码>InnerList=项目作为列表有什么问题??items.ToList()代码>首先?一个问题可能是传递列表
与传递其他IList
的语义。在第一种情况下,您将以对基础列表的引用结束,该列表将在您更改该对象时看到更新。在另一种情况下,您将得到一个列表的副本,该副本不会随着基础IList的更改而更改。@Vova转换是一个非常便宜的操作。它是一个WCF数据协定-它必须使用具体类型进行序列化IIRC。我试图从列表继承自定义列表,但这又是WCF的一个问题(我不记得是哪个问题)。如果IList的某些实现无法转换为List,那么它将转到.ToList()扩展,不是吗?为什么我会在这里出现运行时错误?而且WCF无法为接口成员生成WSDL。@Lucastrezesniewski是的,这是显而易见的,这就是为什么我建议从列表
继承的原因。但是我试图让我的答案更一般化,什么时候使用接口,什么时候使用具体的类。@Vova我必须先看看你从List
继承时遇到的问题,然后我才能帮助你。至于您关于.ToList()
的问题,归根结底是如何使用传递的实例。就像我说的,如果您只使用接口中由定义的公共属性/方法,那么您当然可以。但是如果你尝试使用一些属性/met
InnerList = items.ToList();