阻止 List.Add() 方法

本文关键字:方法 Add List 阻止 | 更新日期: 2023-09-27 18:36:16

我有一个包含私有列表的类。我创建了一个 getter 和一个将元素添加到列表中的方法:

public class Test{
    private List<T> myList;
    public List<T> MyList
    {
        get { return myList; }
    }
    public Test()
    {
         myList = new List<T>();
    }
    public void AddElements(T element)
    {
         // Do dome stuff, subscribe to an event of T
         myList.Add(element);
    }
}

由于每次将元素添加到我的列表中时,我都想做更多的事情,我不希望在代码的某些部分有人直接添加元素:

Test test = new Test();
// Wrong
test.MyList.Add(element);
// Right
test.AddElements(element);

我曾考虑创建一个实现 IList 接口并覆盖 Add() 方法的新类,但我想知道是否有更简单/优雅的方式来"阻止"这个 Add() 方法。

阻止 List.Add() 方法

如果您至少使用 .NET 4.5,请返回一个 IReadOnlyList<T>

public class Test{
    private List<T> myList;
    public IReadOnlyList<T> MyList
    {
        get { return myList; }
    }
    public Test()
    {
         myList = new List<T>();
    }
    public void AddElements(T element)
    {
         // Do dome stuff, subscribe to an event of T
         myList.Add(element);
    }
}

我会以ReadOnlyCollection<T>的身份返回

像这样使用它:

public class Test<T> 
{
    private List<T> myList;
    public ReadOnlyCollection<T> MyList
    {
        get { return myList.AsReadOnly(); }
    }
    public Test()
    {
        myList = new List<T>();
    }
    public void AddElements(T element)
    {
        // Do dome stuff, subscribe to an event of T
        myList.Add(element);
    }
}

这样就可以防止铸造...它将用 ReadOnlyCollection 类包装您的List<>


或者,您可以将其作为Array返回,如下所示:

public T[] MyList
{
    get { return myList.ToArray(); }
}

ToArray()方法将创建列表的副本


当它作为IReadOnlyList<T>返回时。你可以简单地把它扔回去..

Test test = new Test<int>();
test.AddElements(10);
((List<int>)test.MyList).Add(20);
foreach(var i in test.MyList)
    Console.WriteLine(i);

在测试类中,将List公开为IReadOnlyList<T>,那么您将不被允许使用 MyList.直接添加

public class Test{
    private List<T> myList;
    public IReadOnlyList<T> MyList
    {
        get { return myList; }
    }
    public Test()
    {
         myList = new List<T>();
    }
    public void AddElements(T element)
    {
         // Do dome stuff, subscribe to an event of T
         myList.Add(element);
    }
}

编辑将其更新为 IEnumerable 到 IReadOnlyList。使用IReadOnlyList - IEnumerable与IReadOnlyList

如果 getter 的唯一原因是添加元素,则根本不需要直接访问列表,但您可以将对 Add -method的调用包装到您自己的方法中:

class MyClass<T> {
    private List<T> _myList ...
    public void AddElements(T element)
    {
         // Do dome stuff, subscribe to an event of T
         _myList.Add(element);
    }
}

CA1002 进一步避免了公开泛型列表