2016-02-26 73 views
3

我有一个包含私人列表的类。我创建了一个getter和将元素添加到列表中的方法:阻止List.Add()方法

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()方法。

+1

如果你不希望有人能够修改它,不要暴露'List'。您可以公开['ReadOnlyCollection'](https://msdn.microsoft.com/en-us/library/e78dcd75(v = vs.110).aspx),然后没有人可以添加(除非他们使用反射)。 – Sinatr

回答

7

如果您至少使用.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); 
    } 
} 
+0

'((List )test.MyList).Add(....);'? –

+0

@JeroenvanLangen当然,但总有一种方法可以获取数据。 –

+0

我认为这工作得很好,它不会创建副本。像你说的。 “总有一种方法可以获取数据”;-) –

1

如果你吸气的唯一原因是添加你不需额外需要直接访问的列表中的所有元素,但是你可以用呼叫转移到Add - 方法到您自己的方法:

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

+0

不幸的是,我必须使用外部列表中的元素,所以我需要访问它... – Ignacio

3

避免在测试类暴露List然后为IReadOnlyList<T>你不会被允许使用MyList.Add直接

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<T> vs IReadOnlyList<T>

2

我会回来为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(); } 
} 

当它返回一个IReadOnlyList<T>ToArray()方法将创建列表


副本。你可以简单地把它扔回去..

Test test = new Test<int>(); 

test.AddElements(10); 

((List<int>)test.MyList).Add(20); 

foreach(var i in test.MyList) 
    Console.WriteLine(i);