Lista readonly z prywatnym zestawem

Jak mogę wyeksponować List<T> tak, że jest ona tylko do odczytu, ale może być ustawiona prywatnie?

To nie działa:

public List<string> myList {readonly get; private set; }

Even if you do:

public List<string> myList {get; private set; }

Nadal możesz to zrobić:

myList.Add("TEST"); //This should not be allowed

Myślę, że możesz mieć:

public List<string> myList {get{ return otherList;}}
private List<string> otherList {get;set;}
Author: Peter Mortensen, 2011-01-20

15 answers

Myślę, że mieszasz pojęcia.

public List<string> myList {get; private set;}

jest już "tylko do odczytu". Oznacza to, że poza tą klasą nic nie może ustawić myList na inną instancję List<string>

Jeśli jednak chcesz mieć listę readonly, jak w "nie chcę, aby ludzie mogli modyfikować zawartość listy ", musisz ujawnić ReadOnlyCollection<string>. Możesz to zrobić poprzez:

private List<string> actualList = new List<string>();
public ReadOnlyCollection<string> myList
{
  get{ return actualList.AsReadOnly();}
}

Zauważ, że w pierwszym fragmencie kodu inni mogą manipulować listą, ale nie mogą zmienić listy, którą masz. W drugim urywek, inni otrzymają listę tylko do odczytu, której nie mogą modyfikować.

 91
Author: Philip Rieck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-20 17:58:22

Jeśli chcesz używać kolekcji readonly ReadOnlyCollection<T>, nie List<T>: {]}

public ReadOnlyCollection<string> MyList { get; private set; }
 11
Author: Darin Dimitrov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-20 15:32:09

Wolę używać IEnumerable

private readonly List<string> _list = new List<string>();

public IEnumerable<string> Values // Adding is not allowed - only iteration
{
   get { return _list; }
}
 11
Author: Sergey Berezovskiy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-20 15:36:48

Return a ReadOnlyCollection, która implementuje IList

private List<string> myList;

public IList<string> MyList
{
  get{return myList.AsReadOnly();}
}
 10
Author: Sean,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-20 15:33:41

Istnieje kolekcja o nazwie ReadOnlyCollection<T> - tego szukasz?

 4
Author: Joe Enos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-20 15:32:25

Możesz użyć metody List AsReadOnly (), aby zwrócić opakowanie tylko do odczytu.

 4
Author: Etienne de Martel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-20 15:32:31
private List<string> my_list;

public ReadOnlyCollection<string> myList
{
    get { return my_list.AsReadOnly(); }
    private set { my_list = value; }
}
 4
Author: Tesserex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-20 15:33:24
    private List<string> _items = new List<string>();         

    public ReadOnlyCollection<string> Items

    {

        get { return _items.AsReadOnly(); }

        private set { _items = value }

    }
 3
Author: zavaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-20 15:33:54

Here is one way

public class MyClass
    {
        private List<string> _myList;
        public ReadOnlyCollection<string> PublicReadOnlyList { get { return _myList.AsReadOnly(); } }

        public MyClass()
        {
            _myList = new List<string>();
            _myList.Add("tesT");
            _myList.Add("tesT1");
            _myList.Add("tesT2");

            //(_myList.AsReadOnly() as List<string>).Add("test 5");
        }

    }
 3
Author: Dustin Davis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-20 15:53:10

W frameworku. NET 4.5 można wystawiać tylko interfejs IReadOnlyList. Coś w stylu:

private List<string> _mylist;
public IReadOnlyList<string> myList { get {return _myList;} }

Lub jeśli chcesz zapobiec niechcianemu castingowi do IList

private List<string> _mylist;
public IReadOnlyList<string> myList { get {return new List<string>(_myList);} }
 3
Author: Bohumil Janda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-14 15:40:23
private List<string> myList;

public string this[int i]
{
    get { return myList[i]; }
    set { myList[i] = value; }
}
 2
Author: Jonathan Wood,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-20 15:34:16

Dlaczego używasz listy. Brzmi jak to, co naprawdę chcesz ujawnić, to IEnumerable

public IEnumerable<string> myList { get; private set; }

Teraz użytkownicy klasy mogą odczytywać pozycje, ale nie chagnować listy.

 1
Author: tster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-20 15:32:50

Możesz również utworzyć swoją normalną listę, ale wystawić ją za pomocą właściwości typu IEnumerable

private List<int> _list = new List<int>();

public IEnumerable<int> publicCollection{
   get { return _list; }
}
 1
Author: Adam Rackis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-20 15:33:06

Trochę za późno, ale mimo to: nie lubię używać wrappera ReadOnlyCollection, ponieważ nadal wyświetla wszystkie metody modyfikacji kolekcji, które rzucają NotSupportedException, gdy są dostępne w run-time. Innymi słowy, implementuje interfejs IList, ale potem narusza ten sam kontrakt w czasie wykonywania.

Aby wyrazić, że naprawdę ujawniam niezmienną listę, Zwykle uciekam się do niestandardowego interfejsu IIndexable, który dodaje długość i indeks do IEnumerable (opisanego w This CodeProject Artykuł ). Jest to owijarka, tak jak powinno być zrobione w pierwszej kolejności IMHO.

 0
Author: Groo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-03 16:32:49

Nie widziałem jeszcze tej opcji:

private List<string> myList;

public List<string> MyList
{
    get { return myList.AsReadOnly().ToList(); }
}

To powinno pozwolić na ujawnienie listy tylko do odczytu.

 -1
Author: Tim Lehner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-02 22:47:49