.net 新建()或清除(),这就是问题所在

.net 新建()或清除(),这就是问题所在,.net,.net,在我目前的工作场所,我遇到了许多类似于以下示例的代码: private void GetWidgets(ref List<Widget> widgets){ if(widgets == null){ widgets = new List<Widget>(); } else{ widgets.Clear(); } ... code to fill widget list } private void GetWidgets(参考列

在我目前的工作场所,我遇到了许多类似于以下示例的代码:

private void GetWidgets(ref List<Widget> widgets){
  if(widgets == null){
    widgets = new List<Widget>();
  }
  else{
    widgets.Clear();
  }
  ... code to fill widget list
}    
private void GetWidgets(参考列表小部件){
if(widgets==null){
widgets=newlist();
}
否则{
widgets.Clear();
}
…填充小部件列表的代码
}    

公共类小部件{
私有列表小部件;
……其他私人成员
公共窗口小部件(){
清除();
}
公共空间清除(){
if(widgets==null){
widgets=newlist();
}
否则{
widgets.Clear();
}
…初始化其他私有成员
}
}    
我个人发现在这些示例中使用Clear方法会使代码更加丑陋和复杂。我不知道使用Clear方法是否比简单地创建一个新列表有性能提升,但我更喜欢这样的代码:

private List<Widget> GetWidgets(){
  widgets = new List<Widget>();
  ... code to fill widget list;
  return widgets;
}
private List GetWidgets(){
widgets=newlist();
…用于填充小部件列表的代码;
返回窗口小部件;
}

公共类小部件{
私有只读列表小部件=新列表();
……其他私人成员
公共窗口小部件(){
…初始化其他私有成员
}
公共清除(){
widgets.Clear();
}
}
这样的代码迫使您稍微更改开发模式,但我认为它使代码更具可读性并降低了复杂性


除了这是一段匆忙编写的示例代码之外,我还大胆地使用了具体的类而不是接口,等等。;你的意见是什么?每种方法的优缺点是什么

Clear是一个更好的选择,如果您有一个列表的共享引用,其他类可以访问。在这种情况下,更新它将创建一个新的空列表,但是创建了对旧列表的引用的任何其他类仍将看到一个已填充的列表

想象一下这个场景:

List<Widget> first;
myWidgets.GetWidgets(ref first);
List <Widget> second = first;
myWidgets.GetWidgets(ref second);
先列表;
GetWidgets(首先引用);
列表第二=第一;
GetWidgets(参考秒);
在上述情况下,如果使用了
Clear
first
second
将连接到同一个列表。如果使用了
new
,它们将连接到两个完全不同的列表。这两种方法都会产生后果,使用其中一种方法的决定取决于您试图实现的目标

所以我想你的问题的答案是:

  • 当您希望确保对
    GetWidgets
    的每次调用都创建一个独立的、基本上不可变的列表时,
    new
    更好。这在多线程应用程序中更好。如果您以只读列表的形式返回列表,您会得到更好的服务
  • Clear
    在希望表示单个列表时效果更好,并且引用该列表的所有类都可以看到对该列表的更改。如果使用多线程,则会产生许多争用问题

如果对该列表的引用需要这种类型的代码,那么我认为需要重新设计一些东西。尝试使用无副作用的函数,但事实并非如此,因为它既在构造对象,也在操纵状态,这可能会在其他地方产生影响。

我个人喜欢

public class Widgets {
  private readonly List <Widget> widgets = new List<Widget>();
  ... 
  public void Clear() {
      widgets.Clear();
    ...
  }
}
公共类小部件{
私有只读列表小部件=新列表();
... 
公共空间清除(){
widgets.Clear();
...
}
}
列表在一个位置创建,且仅在一个位置创建;Clear()是明确、直接、简单且无条件的。代码越少,复杂性越低

我在这里使用
readonly
来提醒我——当我写错代码时,强制提醒我——我已经完成了列表的创建,重新创建它将是一个错误


<强>更新< /强>由于Joel Mueller的有用注释.< /P>

也有垃圾收集要考虑-如果你正在使用New()很多,那么这将在堆上创建大量对象,这些堆必须是垃圾收集的,但是Car()不会创建任何新堆对象(尽管这只是一个真正的问题,如果你做了几千次的话)

@Michael Meadows-使用接口并不让我感到厌烦。我喜欢接口。我之所以加入这一条款,是因为一些雅虎会听到我没有使用接口而不是我问的问题的事实。:)我相信“只读”将相当于C#关键字-我同意,这是一个很好的做法。@Carl-我真的很喜欢你的想法。感谢您的输入。@JC-我每天看到的很多代码都是遗留代码;其中一些是用其他语言表达的,但这似乎几乎是一种在这里如何表达的“文化”。我总是试图产生无副作用的代码;但我似乎在与其他人进行一场艰苦的斗争,让他们也遵循同样的做法。谢谢你的回复。
List<Widget> first;
myWidgets.GetWidgets(ref first);
List <Widget> second = first;
myWidgets.GetWidgets(ref second);
public class Widgets {
  private readonly List <Widget> widgets = new List<Widget>();
  ... 
  public void Clear() {
      widgets.Clear();
    ...
  }
}