将项添加到列表中,但不起作用

时间:2011-05-13 07:55:24

标签: c# list getter

在C#类中,我有一个列表和两个不同的getter用于列表:

private List<A> a;
public List<A> EveryA
   {
      get
      {
          if (a == null) a = new List<A>();
          return a;
      }
   }
public List<A> FilteredA
   {
       get
       {
          return EveryA.FindAll(a => a.IsInFilter);
       }
    }

现在我的问题是:语法FilteredA.Add(this);怎么样? 它编译并运行但不能将任何项目添加到任何列表中 一个更好的编译器是否必须通知(小)问题?

5 个答案:

答案 0 :(得分:5)

他们不是同一个名单。这不是编译器可以为您检查的东西,因为编译器无法真正读懂您的想法。查看List<T>.FindAll

的文档

结果是一个列表,但它不是同一个列表(怎么可能?你的原始列表没有被过滤!)。

您应该能够将项目添加到FilteredA返回的列表中,但它们不会显示在a中。

我建议您使用LINQ Where代替IEnumerable<T>。这样,显然FilteredA的结果不应该改变,只能迭代:

public IEnumerable<A> FilteredA
{
    get { return EveryA.Where(a => a.IsInFilter); }
}

答案 1 :(得分:3)

没有。为什么要通知你这个?完全没问题 FilteredA不会返回a,而是List<A>的新实例 FilteredA.Add(this);this添加到此新实例。

请参阅此代码:

var filteredA = FilteredA;
int count1 = filteredA.Count;
filteredA.Add(this);
int count2 = filteredA.Count;
Assert.AreEqual(count1 + 1, count2);

这表明新项目已添加到列表中。但是对于那个与你班级里面的列表无关的新实例。

答案 2 :(得分:3)

FindAll返回一个新列表。您想将新项目添加到新列表中,但不保留对新列表的引用。如果过滤后的列表来自方法而不是属性,则语义会更清晰。

答案 3 :(得分:2)

public List<A> FilteredA返回FindAll方法的一些输出,作为List<A>。这与EveryA不同,因此当它超出范围时,您的添加将会丢失。

答案 4 :(得分:1)

这不是一个真正的编译器问题 - 因为代码有效它会编译得很好。问题更多的是代码质量水平。要捕获这样的内容,您可以使用FxCop之类的工具来分析代码。

这两种方法都可以看作是查询方法。您不应将结果公开为List,而应公开IEnumerable或A []。如果要将项目添加到列表中,请使用Add方法执行此操作。

private List<A> items = new List<A>();

public IEnumerable<A> EveryA
{
  get { return items; }
}

public IEnumerable<A> FilteredA
{
  get { return items.Where(item => item.IsInFilter); }
}

public void AddItem(A item)
{
  items.Add(item);
}