Почему это работает только при использовании ключевого слова ref?

У меня есть этот класс контейнера:

class Fruit
{
    public Apple apple;
    public Banana banana;
}

И у меня есть функция в другом классе, которая выглядит так:

public void ChangeFruit(Fruit fruit)
{
    fruit.apple = memberApple;
    fruit.banana = memberBanana;
}

И это прекрасно работает.

Однако я хочу знать, почему это не работает:

Если я изменю метод ChangeFruit, чтобы вместо контейнера брать фактические классы фруктов, например:

public void ChangeFruit(Apple apple, Banana banana)
{
    apple = memberApple;
    banana = memberBanana;
}

Тогда это не работает, если ключевое слово ref не передается с каждым аргументом. Почему мне нужно ключевое слово ref здесь, а не там?

Кстати, при вызове последнего ChangeFruit я вызываю его так:

ChangeFruit(myFruit.apple, myFruit.banana);

В отличие от ChangeFruit(myFruit);

Я просто хочу знать, что при передаче класса контейнера мне не нужно ключевое слово ref, но когда я передаю каждый фрукт по отдельности, мне это нужно. В любом случае я передаю myFruit, за исключением того, что в последнем примере я просто передаю его переменные-члены по отдельности, а не весь контейнер.


person Joey Williams    schedule 31.08.2011    source источник
comment
stackoverflow.com/questions/635915/   -  person Brian Roach    schedule 31.08.2011


Ответы (1)


когда вы вызываете ChangeFruit(myFruit.apple, myFruit.banana);, вы передаете копии ссылок на эти свойства в классе Fruit. Только эти копии изменяются в вашей функции. На самом деле то, что вы делаете, - это поместить новую ссылку на вашу копию, которая никоим образом не изменит ваш исходный объект.

Когда вы используете ключевое слово ref, вы передаете ссылку на эти типы, а не копию

Но когда вы звоните ChangeFruit(myFruit);. вы передаете копию ссылки на ваш container.that указывает на тот же объект в куче. и вы изменяете его содержимое.

person Ashley John    schedule 31.08.2011
comment
Хорошо, спасибо, я понял. Однако что, если я не хочу изменять переменную сразу после ее передачи? Как я мог заставить что-то подобное работать? pastebin.com/8WBHJnj3 - person Joey Williams; 31.08.2011
comment
Не уверен, правильно ли я понял ваш вопрос. Но в методе DoSomethingWithApple() вы добавляете новую ссылку на свое поле apple в своем классе, и это будет отражено после вашего вызова этого метода. - person Ashley John; 31.08.2011