2014-10-14 6 views
3

Рассмотрим следующий код:Почему компилятор C# допускает неправильное совпадение типа возвращаемого значения и типа переменной?

static void Main() 
{ 
    dynamic a = 1; 
    int b = OneMethod(a); 
} 

private static string OneMethod(int number) 
{ 
    return ""; 
} 

Пожалуйста, обратите внимание, что type of b и return type of OneMethod не совпадает. Тем не менее он создает и генерирует исключение во время выполнения. Вопрос в том, почему компилятор допускает это? Или что это за философия?

Причиной этого может быть Compiler does not know which OneMethod would be called, because a is dynamic. Но почему он не видит, что есть только один OneMethod. Во время выполнения обязательно будет исключение.

+9

Прочитайте [MSDN] (http://msdn.microsoft.com/en-us/library/dd264741.aspx) (первое предложение): _ «Динамический тип включает операции, в которых это происходит, с обходным компилятором ** -time type **. Вместо этого эти операции разрешаются во время выполнения. "_ –

+0

@TimSchmelter благодарит вас. На самом деле я не искал MSDN. Но мой вопрос заключался в том, что в чем причина (или философия) за этим? – serdar

+3

вам нужно спросить E.Lippert, я думаю, он ответил бы на что-то вроде «если вы используете динамический, компилятор больше не отвечает за проверку переменной или любого задействованного выражения». –

ответ

3

Любое выражение, имеющее операнд типа dynamic, будет иметь тип самой динамики.

Таким образом, ваше выражение OneMethod(a) возвращает объект, который набранный динамически

поэтому первая часть кода эквивалентна

static void Main() 
{ 
    dynamic a = 1; 
    dynamic temp = OneMethod(a); 
    int b = temp; 
} 

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

private static T OneMethod<T>(T number) 

Теперь компилятор не будет знать тип, возвращаемый до выполнения. Он даже не знает, какой метод вызывается. Общий или не общий. Разве вы не удивились бы, если бы в первом случае это событие было присвоено как ошибка компиляции, а затем, добавив совершенно другой метод, он был перенесен на ошибку времени выполнения?

+1

Но какое значение может иметь 'a' - что изменит тип возврата' OneMehtod'? –

+0

@JensKloster см. Редактирование. В общем случае компилятор не может знать, какой тип возвращается, потому что это означает, что он должен выбрать правильный метод в первую очередь. Однако для этого вам нужно будет узнать тип аргумента, который не может быть компилятором, потому что вы попросили его не интересоваться (т. Е. Объявив тип динамическим) –

+0

@RuneFS: есть ли у вас источник (документация или спецификация C#), которая подтверждает ваше первое предложение? –