Почему я должен указать ключевое слово "out" в C #? - PullRequest
3 голосов
/ 07 марта 2009

Прежде чем задать свой вопрос, посмотрите на этот пример функции:

DateTime.TryParse("01/01/2000", out oDate)

Зачем мне нужно указывать ключевое слово out? Разве компилятор не должен знать это из определения функции?

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

Я также должен уточнить, что я спрашиваю, в частности, о компиляторе C # .NET 3.5.

Ответы [ 6 ]

17 голосов
/ 07 марта 2009

Компилятор может подразумевать ключевое слово out , которое может подразумевать , но, насколько я понимаю, команда C # решила сделать ключевое слово out, явно требуемое вызывающей функцией, для увеличения видимости в отношении характера параметр.

10 голосов
/ 07 марта 2009

Компилятор знает, вы не можете. Это способ сообщить вам, что передаваемый вами параметр может измениться в той функции, которой вы его передаете.

6 голосов
/ 07 марта 2009

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

Многое из этого имеет свои корни в C ++, где для ссылочного значения не требуется монитор сайта вызовов. Невозможно посмотреть на вызов C ++ и точно знать, что он будет делать. Параметры, передаваемые по ссылке и значению в C ++, имеют огромные различия в семантике.

2 голосов
/ 07 марта 2009

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

В языке C # есть много того, что я бы назвал сетями безопасности, которые явно сообщают программисту, что происходит. Вот пара примеров:

  1. Не проваливаться в выражениях switch.
  2. Вы не можете присвоить значение в операторе if: if (x = 5) выдает ошибку вместо оценки в true.
1 голос
/ 07 марта 2009

http://msdn.microsoft.com/en-us/library/t3c3bfhx(VS.80).aspx

"Ключевое слово out вызывает передачу аргументов по ссылке. Это похоже на ключевое слово ref, за исключением того, что ref требует, чтобы переменная была инициализирована перед передачей. Чтобы использовать параметр out, нужно определить как определение метода, так и вызывающий метод. необходимо явно использовать ключевое слово out. "

Поскольку DateTime.TryParse не требует инициализации oDate, необходимо передать ключевое слово out.

0 голосов
/ 07 марта 2009

ОК, я не эксперт по C #, так что если я все испорчу, пожалуйста, поправьте меня?

Существует два способа передачи параметра в функцию C #: по значению и по ссылке. Здесь большая разница в том, изменяет ли параметр внутри функции переменную, используемую для ее вызова. Это не то, что я бы доверил компилятору, который решит сам.

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

Другой вопрос: нужно ли его инициализировать или нет. C # любит отлавливать, когда переменные используются неинициализированными, поскольку это почти всегда ошибка. В этом случае вы можете просто объявить, что вы передаете, и использовать TryParse (), чтобы присвоить ему первое значение. Это совершенно законная методика, поэтому компилятор должен это разрешить. Это еще одна вещь, которую я бы не доверял компилятору, чтобы получить права. (Я предполагаю, что компилятор также проверяет, что перед использованием в TryParse () инициализируется выходной параметр.)

Итак, «out» служит двум целям. Он устанавливает, что параметр передается по ссылке, и ожидается, что он будет инициализирован внутри функции. Ни один из них не может быть определен компилятором.

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