Передача объектов по ссылке или нет в C # - PullRequest
4 голосов
/ 15 мая 2010

Предположим, у меня есть такой класс:

public class ThingManager {
    List<SomeClass> ItemList;

    public void AddToList (SomeClass Item)
    {
        ItemList.Add(Item);
    }

    public void ProcessListItems()
    {
        // go through list one item at a time, get item from list,
        // modify item according to class' purpose
    }
}

Предположим, что SomeClass - это довольно большой класс, содержащий методы и члены, которые являются довольно сложными (например, List <> s и массивы) и что их может быть большое количество, поэтому не нужно копировать большие объемы данных программа важна.

Должен ли метод "AddToList" содержать "ref" или нет? И почему?

Это все равно что пытаться снова и снова изучать указатели в C ;-) (возможно, поэтому я запутываюсь, я пытаюсь связать их с указателями. В C это будет "SomeClass * Item" и список переменных "SomeClass *")

Ответы [ 4 ]

17 голосов
/ 15 мая 2010

Поскольку SomeClass является классом, то он автоматически передается по ссылке на метод AddToList (или, точнее, его ссылка передается по значению), поэтому объект не копируется. Вам нужно использовать ключевое слово ref, только если вы хотите переназначить объект, на который указывает ссылка, в методе AddToList, например, Item = new SomeClass();.

2 голосов
/ 15 мая 2010

Поскольку SomeClass является ссылочным типом, вам не нужно использовать ключевое слово "ref". Если бы это был тип значения, «ref» может быть полезным.

1 голос
/ 15 мая 2010

Думайте о out как о способе заставить параметр работать как возвращаемое значение.

Итак, они очень похожи:

void Foo(out int result)
{
    result = 5;
}

int Foo()
{
    return 5;
}

А затем подумайте о ref как о способе разрешения параметру быть и входом, и выходом.

Итак, в вашем примере, если вы объявили свой метод:

public void AddToList(ref SomeClass Item)

Тогда вызывающий абонент должен написать что-то вроде:

SomeClass i = null;
obj.AddToList(ref i);

Это было бы незаконно, например:

obj.AddToList(ref new SomeClass());

Они будут вынуждены передавать имя переменной, а не выражение, чтобы метод AddToList мог сохранить значение в переменной. Добавляя префикс ref, вы разрешаете своему методу указывать переданную переменную на другом объекте.

0 голосов
/ 15 мая 2010

Если вам когда-либо понадобится использовать исходное значение параметра user ref. Если нет, используйте. Для справки:

http://www.yoda.arachsys.com/csharp/parameters.html

http://msdn.microsoft.com/en-us/library/0f66670z(VS.71).aspx

...