2012-04-19 5 views
3

Я сейчас смотрю на какой-то код на C#, и я хотел проверить, что я не схожу с ума в своем понимании того, как он должен работать.Почему ключевое слово «ref» используется с System.ServiceModel.Channels.Message?

Это связано с прохождением вокруг System.ServiceModel.Channels.Message. Каждый метод, который принимает объект Message имеет сигнатуру метода, похожее на это:

void SomeMethod(ref Message message) { ... } 

То, что я не понимаю, почему «ссылка» ключевое слово там. Насколько я понимаю, если метод не собирается полностью заменить объект, тогда он не нужен.

void SomeMethod(ref Message message) 
{ 
    message = new Message(); 
} 

Но если сообщение, например, только добавляет что-то еще к заголовкам, или просто считывает значение из объекта, то ключевое слово «ссылка» не нужна, как сообщение является ссылочным типом.

void SomeMethod(Message message) 
{ 
    message.Headers.Add("Some Data"); // This should be fine? 
} 

Приветствия

+0

Согласитесь, что неясно, почему код принимает параметр 'ref'. Возможно, какой-то дополнительный контекст поможет. – Jon

+0

Я боюсь, что это примерно столько, сколько у меня есть, я посмотрел документацию MS, и кажется, что каждый метод, который принимает объект этого типа, делает это с помощью ключевого слова «ref»? –

ответ

8

Во-первых, вы, вероятно, правильно; вполне вероятно, что человек, который написал код, добавил ошибку «ref».

Я хочу воспользоваться этой возможностью, чтобы убедиться, что вы четко понимаете, что означает «ref». Это означает, что «сделать псевдоним этой переменной». То есть, когда вы говорите:

M(ref string x) { x = null; } 
N(string x) { x = null; } 
... 
string y = "abc"; 
N(y); 
M(ref y); 

Вызов к N(y) средства сделать копию справки, которая находится в г, и поставить эту ссылку в х. Вызов M(ref y) означает x и y теперь оба имени для одной и той же переменной. То есть x становится псевдоним для y.

К сожалению, мы выбрали «ref» как ключевое слово, потому что это сразу заставляет людей путать о ссылочных типах и типах значений. Он не имеет ничего общего со ссылочными типами и типами значений. «ref» означает «Я имею в виду другую переменную».

Разница между ref и out ничего более ref не требует, чтобы алиас переменного инициализируются перед тем вызова и out не делают. (Оба гарантируют, что переменная будет инициализирована после звонок завершается нормально.)

+1

Я на самом деле склонен согласиться с выбором «ref», поскольку это означает двойное косвенное использование при использовании ссылочных типов («ссылка на ссылку»). И наоборот, если ключевое слово было, скажем, «псевдоним» или «var», или «byname» и т. Д., То смысловое сходство может быть камнем преткновения ... – Alan

+2

@Alan: Я вижу вашу точку зрения. Но «ref» действительно выражает * деталь реализации *.Тот факт, что да, это ссылка на место хранения, содержащее ссылку на место хранения, интересен с точки зрения разработчика компилятора, но он мало говорит пользователю, который, в конце концов, не имеет другого способа чтобы воспользоваться этой детальностью реализации. –

+1

И я вижу твое. Правда состоит в том, что через некоторое время происходит слияние истинной семантики (как в «ссылочном типе») и конкретной реализации (как в «ссылке на место хранения»), но да, использование «псевдонима» могло бы привести к меньшему недоразумению с «обычные» программисты, в то время как авторы компилятора все равно знают детали. – Alan

Смежные вопросы