2015-10-19 6 views
2

У меня есть некоторые наследие C# код с помощью следующей части:AddRange в поддавки доступ общественности к списку

private List<MyClass> mList = new List<MyClass>(); 

public List<MyClass> getList() 
{ 
    List<MyClass> list = new List<MyClass>(); 
    list.AddRange(mList); 
    return list; 
} 

Не уверен, что цель AddRange здесь? Могу ли я переписать как:

public List<MyClass> getList() 
{ 
    return mList; 
} 
+3

Да. Из показанного кода этого должно быть достаточно. –

+4

Не совсем то же самое, поскольку 'getList' создает новый список с теми же объектами, тогда как' return mList' возвращает даже тот же список. Поэтому, если вы будете называть 'getList(), Clear()' также будет очищен исходный список. –

+0

Это свойство имеет уродливый побочный эффект, потому что это означает, что вы можете изменить состояние класса-владельца, изменив возвращаемый список. Возвращение 'IEnumerable' или создание его метода было бы подходящей задачей. – Silvermind

ответ

5

No.

Если вы просто используете return mlist, вы вернете экземпляр mlist, в то время как исходный код возвращает неполную копию.


Предположим, что ваш класс выглядит следующим образом:

class Foo 
{ 
    public Foo() 
    { 
     mList.Add(1); 
    } 

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

    public List<int> getList() 
    { 
     List<int> list = new List<int>(); 
     list.AddRange(mList); 
     return list; 
    } 
} 

И теперь вы бежите

var x = new Foo(); 
x.getList().Add(2); 
x.getList().Add(3); 

Содержание mList все равно будет один 1, потому что звонки на getList вернулись копии mList, а не сам список.

Если изменить код, как вы делали в вашем вопросе, вы изменили бы mList он теперь будет содержать элементы 1, 2 и 3.


Это не ясно из названия метода, что копия возвращается, так что вы, возможно, хотите изменить его на что-то вроде GetListCopy (в этом случае метод может просто вернуть new List<MyClass>(mList) или mList.ToList()), или возвращает список как a IReadOnlyList, чтобы уточнить, что список не следует изменять.

public IReadOnlyCollection<MyClass> getList() 
{ 
    return mList.AsReadOnly(); 
} 
+1

Не хватает объяснений –

+0

@TimSchmelter Как вы думаете, не объяснено? Исходный код возвращает копию списка, новый код возвращает экземпляр 'mList'. – sloth

+2

OP, похоже, не очень хорошо знаком с C# и задает основной вопрос. Поэтому ответ на то, что он возвращает мелкую копию вместо исходного списка, может быть правильным, но не очень полезно, если OP не знает, что это значит. Когда это имеет значение/имеет значение? (т. е. если вы вызываете 'Clear()') –

0

Нет, вы не можете. Это может привести к неожиданному поведению в вашем программном обеспечении, потому что код, поскольку он создает новый экземпляр List, и ваше решение имеет тот же экземпляр, возвращаемый каждый раз при вызове метода.

2

Как уже указано, если вы используете только return mList;, он вернет исходный список, а не его копию.

Однако вы можете упростить его с помощью:

public List<MyClass> getList 
{ 
    return mList.ToList(); // returns copy of original list 
} 
0

Единственная цель здесь, чтобы клонировать первоначальный список, чтобы сохранить его без изменений. Но, лучше переписать эту собственность и превратить его в метод:

public List<MyClass> getList() 
{ 
    // note, that Enumerable.ToList() does the same 
    return new List(mList); 
} 

List<T> конструктор проверяет ICollection<T> реализации в источнике IEnumerable<T> и правильно устанавливает начальную емкость. Поскольку каждый вызов будет создавать новый экземпляр, это не должно быть свойством, а методом.

0

Комментарий Тима и Sloth уже дает правильное объяснение.

Просто дополнительный пункт:

private List<MyClass> mList = new List<MyClass>(); 

public List<MyClass> getList1() 
{ 
    List<MyClass> list = new List<MyClass>(); 
    list.AddRange(mList); 
    return list; 
} 

public List<MyClass> getList2() 
{ 
    return mList; 
} 

getlis1() -
(1) Сохраняет первоначальный список сейф. Add() или AddRange() или Clear() не влияет на него.
(2) Throws исключение если mList есть null!

getlis2() -
(1) Предоставляет исходный список mList. Add() или AddRange() или Clear() влияет (изменяет) его.
(2) Возвращает null если mList - null!

Смежные вопросы