Передача по ссылке и использование ссылки - PullRequest
2 голосов
/ 05 августа 2010

Я посмотрел на подобные вопросы и прочитал несколько статей. Эта статья содержит несколько картинок, которые проясняют ее.

SomeObject so = new SomeObject();
somefunction(so);
Console.write(so.x); // will print 1

SomeObject so1 = new SomeObject();
somefunctionByRef(so1);
Console.write(so1.x); // will print 1


static void somefunction(SomeObject so)
{
    so.x = 1;
}

public void somefunctionByRef(ref SomeObject so)
{
    so.x = 1;
}

Оба метода одинаково влияют на этот ссылочный тип. так зачем выбирать ref ключевое слово для ссылочных типов?

Это плохая практика (возможно, ложная) использовать somefunction (SomeObject так) и изменять объект внутри метода и ожидать изменений без использования ключевого слова ref?

Ответы [ 4 ]

3 голосов
/ 05 августа 2010

Передача параметров по умолчанию в .Net выполняется по значению.Это верно как для типов значений, так и для ссылочных типов.Разница заключается в том, что со ссылочным типом вы передаете ссылку на экземпляр по значению в сравнении с реальным объектом.

Эффект является ссылкой so в исходной функции, а некоторые функции являются независимыми.Изменение экземпляра, на который ссылается ссылка, не влияет на другой.Однако, поскольку они ссылаются на один и тот же объект, они могут видеть мутации этого объекта, сделанные другим (именно поэтому x изменяется в вашем примере)

SomeObject so = new SomeObject();
so.x = 42;
somefunction(so);
Console.Write(so.x); // will print 42

static void somefunction(SomeObject so) {
  so = new SomeObject();
  so.x = 13;
}

Модификатор ref вызывает передачу параметрассылка вместо значения.Фактически, копия ссылки отсутствует, so в исходной и вызывающей функциях - это одна и та же ссылка.Таким образом, сброс одного сбрасывает другой

SomeObject so = new SomeObject();
so.x = 42;
somefunction(ref so);
Console.Write(so.x); // will print 13

static void somefunction(ref SomeObject so) {
  so = new SomeObject();
  so.x = 13;
}
1 голос
/ 05 августа 2010

Классы уже передаются по ссылке (в неуправляемых терминах, так же как и указатель на объект). Передача ссылки позволяет вам изменить базовую переменную (вы используете указатель на указатель). Возьми этот код:

static void foo(SomeObject so)
{
    so.x = 1;
    so = null;
}

static void bar(ref SomeObject so)
{
    so.x = 1;
    so = null;
}

SomeObject so1 = new SomeObject(); 
foo(so1); 
Console.write(so1.x); // will print 1 
bar(so1); 
Console.write(so1.x); // crash

Первый метод будет работать, и вы распечатаете 1 - присвоение нулю просто изменяет локальную для функции переменную. Второй вызовет сбой (NullReferenceException), так как для so1 установлено значение null.

1 голос
/ 05 августа 2010

Я использую ref только при работе с не ссылочными типами, например, int, decimal и т. Д.

взгляните на эту страницу MSDN , чтобы получить более четкое объяснение и немногоГоча

0 голосов
/ 05 августа 2010

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

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