2009-03-06 2 views
3

Прежде чем задать свой вопрос, пожалуйста, посмотрите на этот пример функции:Почему я должен указать ключевое слово «out» в C#?

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

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

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

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

ответ

17

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

+0

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

+0

Это был лучший ответ. Спасибо :) – GateKiller

+2

"потому что Андерс Хейлсберг сказал так" – BCS

10

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

2

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

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

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

Технически № 2 неверно. Техническое определение состоит в том, что вещь внутри оператора if должна принимать логическое значение. x = 5 возвращает int, который не является bool, поэтому компилятор жалуется. Однако справедливо следующее: bool foo = false, bar = false; if (foo = bar) {} – FryGuy

6

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

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

1

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

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

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

0

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

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

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

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

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

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