Подтвердить что ты не робот

С# передать значение/ref?

Общий вопрос, но я мог бы использовать "английское" объяснение.

Ist это похоже на Java, где

Cat myCat

На самом деле это указатель на Cat?

Должен ли я создавать конструкторы копирования в С#?


Я понимаю, что мы проходим по значению, но теперь мой вопрос заключается в том, что мы передаем значение указателя или полную копию объекта?

если его последняя, ​​разве это слишком дорогостоящая производительность/память? Это когда вам нужно использовать ключевое слово ref?

4b9b3361

Ответ 1

Как ответил @rstevens, если это класс, myCat является ссылкой. Но если вы передаете myCat вызову метода, то сама ссылка передается по значению - т.е. сам параметр будет ссылаться на тот же объект, но это совершенно новая ссылка, поэтому, если вы присваиваете ему значение null или создаете новый объект, старая ссылка myCat по-прежнему будет указывать на исходный объект.

SomeMethod(myCat);

void SomeMethod(Cat cat)
{
    cat.Miau(); //will make the original myCat object to miau
    cat = null; //only cat is set to null, myCat still points to the original object
}

У Джона Скита есть хорошая статья об этом.

Ответ 2

Помните, что указатель не совсем такой же, как ссылка, но вы можете просто подумать об этом так, как хотите.

Клянусь, я видел еще один вопрос о том, что это не 10 минут назад, но я не могу найти ссылку сейчас. В другом вопросе, который я видел, они говорили о передаче аргументов по соотношению vs по значению, и это сводилось к следующему:

По умолчанию в .Net вы не передаете объекты по ссылке. Вы передаете ссылки на объекты по значению.

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

Ответ 3

Если вы делят Cat как

class Cat {...}

то это.

Если вы разделили Cat как

struct Cat {...}

то ваша переменная "есть" сама структура.

Это различие между ссылочными типами и типами значений в .Net.

Ответ 4

Да, это о указателях, но на самом деле... Дело в том, что это изначально связано с тем, что речь не идет о защите вашей переменной от изменений в методе. Если вы измените объект внутри метода, эти изменения будут видны внешним методам независимо от того, передано ли оно в "ref" или нет.

Разница (как я понимаю) заключается в том, будет ли переменная, которую вы отправляете, обновить ссылку, если вы измените объект, который ссылается на переменную. Так что данный метод

public void DoSomething(ref CoolShades glasses)
{
    glasses.Vendor = "Ray Ban";
    glasses = new CoolShades();
}

переменная, которую вы передали в качестве параметра, теперь содержит ссылку на новый CoolShades, а не на какой-либо объект, на который он ссылался ранее. Исходное свойство объекта Vendor объекта параметра будет изменено на "Ray Ban" независимо от того, прошел ли вы параметр ref или нет.