Область применения .NET (Of T). Обратный метод - PullRequest
2 голосов
/ 07 апреля 2009

У меня есть простая функция, которая принимает параметр List. Работая с ним, он копирует его и переворачивает копию, используя метод * .NET 100 * * List (Of T).

Private Function FindThing(ByVal Things As List(Of Thing)) As Thing
    Dim ReverseOrderThings As List(Of Thing) = Things
    ReverseOrderThings.Reverse()
    For Each t As Thing In ReverseOrderThings
        ...
    Next
    Return Nothing
End Function

Мой параметр определен как ByVal . Но, похоже, что ByVal не мешает коду в процедуре изменить порядок списка.

Dim Things As List(Of Thing) = GetSortedListFromSomewhere()
Dim FoundThing As Thing = FindThing(Things)
For Each t As Thing In Things
    ...
    'OMG! My Things are in reverse order!!1! WTF?'
Next

Как я могу защитить свой список параметров в такой функции?


Обновление:

Это правильный способ сделать копию списка.

Dim ReverseOrderThings As List(Of Thing) = New List(Of Thing)(Things)

Теперь на список, переданный в качестве параметра, метод Reverse () не влияет.

Ответы [ 6 ]

6 голосов
/ 07 апреля 2009

Сделайте копию списка.

Функция не может изменить значение списка, и фактически это не так. Это меняет то, что содержит список, что разрешено. Единственное, что запрещено, - это присвоение переменной для ссылки на новый список.

3 голосов
/ 07 апреля 2009

Даже если список передан ByVal, передается ByVal сама ссылка, поэтому вы копируете местоположение списка, которое, когда используется, является тем же объектом списка. Я согласен с rossfabricant, что вам следует создать копию списка самостоятельно.

3 голосов
/ 07 апреля 2009

Чтобы защитить список, вам нужно будет сделать его копию перед сортировкой.

Things = New List(Of Thing)(Things)
1 голос
/ 07 апреля 2009

Однако, если аргумент является ссылочным типом, процедура может изменить содержимое или члены базового объекта.

от MSDN

То есть ByVal защищает от изменения только значения-типы

1 голос
/ 07 апреля 2009

Вы не можете напрямую защитить его.

Поскольку List (Of Thing) является ссылочным типом (классом), он передает ссылку ByVal, но содержимое списка по-прежнему может изменяться в вашей подпрограмме (не сама ссылка List, а то, что содержится в списке) .

Чтобы защитить исходный список, вам необходимо скопировать его в новую коллекцию и отсортировать эту коллекцию. Если список содержит ссылочный тип (Thing), это будет относительно недорого.

0 голосов
/ 07 апреля 2009

Ваш параметр передает ссылку на список по значению, а не сам список. Как уже отмечали другие, вам нужно сделать копию, метод расширения ToList() LINQ сделает это легко.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...