【问题标题】:C# - Accessing Lists from another Class or copying it? - Performance & Best PracticeC# - 从另一个类访问列表或复制它? - 性能和最佳实践
【发布时间】:2016-10-12 03:04:53
【问题描述】:

我有一个关于性能和最佳实践的一般性问题。

当使用来自不同类的列表(或任何其他数据类型)时,哪种做法更好?在开始时复制,与本地合作,然后将其重新复制到原件,还是总是访问原件

一个例子:

访问原文:

        public class A
        {
            public static List<int> list = new List<int>();
        }

        public class B
        {

            public static void insertString(int i)
            {
                // insert at right place
                int count = A.list.Count;
                if (count == 0)
                {
                    A.list.Add(i);
                }
                else
                {
                    for (int j = 0; j < count; j++)
                    {
                        if (A.list[j] >= i)
                        {
                            A.list.Insert(j, i);
                            break;
                        }
                        if (j == count - 1)
                        {
                            A.list.Add(i);
                        }
                    }
                }
            }
        }

如您所见,我多次访问原始 List A.list。这里是替代方案:

复制:

        public class A
        {
            public static List<int> list = new List<int>();
        }

        public class B
        {

            public static void insertString(int i)
            {

                List<int> localList = A.list;

                // insert at right place
                int count = localList.Count;
                if (count == 0)
                {
                    localList.Add(i);
                }
                else
                {
                    for (int j = 0; j < count; j++)
                    {
                        if (localList[j] >= i)
                        {
                            localList.Insert(j, i);
                            break;
                        }
                        if (j == count - 1)
                        {
                            localList.Add(i);
                        }
                    }
                }

                A.list = localList; 
            }
        }

在这里,我只访问了另一个类中的列表两次(在开头获取它并在结尾设置它)。哪个会更好。

请注意,这是一个一般性问题,算法只是一个示例。

【问题讨论】:

  • 我很确定,在这两个示例中,您使用的是相同的列表,即使在第二个示例中,您也直接将 localList 分配给 A.list。由于它们是引用类型,我会假设它们是完全相同的列表。要使 localList 成为真正的第二个列表,您需要添加 ... List localList = A.list.ToList();或迭代 A.list 中的每个项目并将每个项目添加到 localList 之前。
  • 感谢迈克尔的回答。我没想到列表是引用类型。我假设因为它是一个引用类型,所以使用 A.list 而不是本地列表会更快,因为我不需要复制 A.list 中的所有元素。对吗?

标签: c# performance list class copy


【解决方案1】:

我不会在这里考虑性能,而是专注于最佳实践:

给出整个 List 违反了封装。 B 可以在 A 不注意的情况下修改 List 及其所有元素(如果 A 从不使用 List 本身但随后 A 甚至不需要存储它)。

一个简单的例子:A 创建列表并立即添加一个元素。随后,A 不再检查List.Count,因为它知道List 不能为空。现在 B 出现并清空列表...

所以每当 B 发生变化时,您还需要检查 A 以查看 A 的所有假设是否仍然正确。如果您对代码有完全的控制权,这就够让人头疼的了。如果其他程序员使用您的类 A,他可能会对 List 做一些意想不到的事情,并且从不检查是否正常。


解决方案:

  • 如果 B 只需要遍历元素,请编写 IEnumerable 访问器。如果 B 不能修改元素,则让访问者交付副本。

  • 如果 B 需要修改列表(添加/删除元素),或者给 B 一份列表的副本(如果他们不需要修改)并接受来自 B 的新 List 或像以前一样使用访问器并实现必要的 List 操作。在这两种情况下,A 都会知道 B 是否修改了列表并做出相应的反应。

例子:

class A
{
  private List<ItemType> internalList;

  public IEnumerable<ItemType> Items()
  {
    foreach (var item in internalList)
      yield return item;
      // or maybe  item.Copy();
      //           new ItemType(item);
      // depending on ItemType
  }

  public RemoveFromList(ItemType toRemove)
  {
    internalList.Remove(toRemove);
    // do other things necessary to keep A in a consistent state
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-07
    • 2020-10-20
    • 2013-11-18
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多