2013-06-08 3 views
2

Я видел многочисленные сообщения о перегрузке метода, изменяя его тип возвращаемого значения, но в идеале, следующая программа должна идеально работать, потому что переменная i типа integer может хранить только целые значения.Почему этот метод перегружает аномалию?

Таким образом, в идеале должен вызвать функцию функции int print(int a) и даже не смотреть на функции float print(int a), потому что она возвращает значение с плавающей точкой, и в main(), я использовал целочисленную переменную для хранения значения, возвращаемого методом, и целая переменная не может иметь значение с плавающей точкой ..

следующий код демонстрирует это →

class temp 
{ 
    public float print(int a) 
    { 
     int l=12.55; 
     return l; 
    } 

    public int print(int a) 
    { 
     int p=5; 
     return p; 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     temp t=new temp(); 
     int i=t.print(10); 
     A.Read(); 
    } 
} 

В другом сценарии, где я сделать что-то вроде этого →

class temp 
{ 
    public float print(int a) 
    { 
     int l=12.55; 
     return l; 
    } 

    public int print(int a) 
    { 
     int p=5; 
     return p; 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     temp t=new temp(); 
     float f=t.print(10); 
     A.Read(); 
    } 
} 

Здесь я принимаю, что компилятор должен генерировать ошибку, потому что он падает в дилемме ли назвать public int(int a) или public float(int a), а так как переменные типа поплавка может одновременно удерживая целое и поплавок значение ..

+0

Пожалуйста, не смешивайте C# и Java, как будто они имеют одинаковое поведение в этом случае. –

+3

@Luiggi: позволяет ли Java перегрузки различаться только по типу возврата? – Vlad

+0

Java не позволяет, что вы просите. Чтобы заставить его работать на Java, вы должны хотя бы изменить один из параметров. –

ответ

12

В C# нет перегрузки с возвратным типом. Что, если вы проигнорировали возвращаемое значение или назначили его объекту? Тогда какая перегрузка будет вызвана? Существует так много неоднозначных сценариев, что было бы практически невозможно реализовать.

+0

да .. его правда .. thnks для информации .. –

+0

Действительно. 'var i = t.print (10);' нужно будет строго напечатать, но к чему? –

5

Это не из-за этого, из-за других сценариев.

Например, вы знаете, когда вы вызываете Console.ReadLine(), только чтобы ждать ввода пользователя? (например, нажмите enter для продолжения)? В этом случае вы можете сделать то же самое с вашим методом print. Какой из них следует назвать тогда? Должен ли он вызвать метод float? Должен ли он вызвать метод int? Что происходит, когда они используют var? dynamic? Дженерики?

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

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

Короче говоря: это возможно, но это так, так непрактично, что никогда не будет рассматриваться как желательные разработчиков языка [1].

[1]: Интересное оповещение, MSIL позволяет. Так что если вы использовали ildasm, вы можете получить .В основном потому, что для вызова функции в нем, что вам нужно сделать это: call MyReturnType MyFunc(MyType, MyOtherType)

+2

Похож на 3 краткими линиями, бьет 9 или более линий. –

+0

Здесь есть верхняя часть. –

+0

Даже это объясняет очень хороший сценарий .. !! наверняка заслуживает upvote .. –

0

говорит, что вы имели

int foo(int a){..} 
double foo(int a) {...} 

, а затем называетесь

foo(1); 

или уаг х = Foo (1);

Итак, какой из них вы хотели назвать?

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

Помимо того, что это PIA для дизайнера языка, что относительно программиста? Видя, как это легко исправить с помощью fooInt и FooFloat, почему кто-то выбирает дополнительный уровень сложности (не говоря уже о производительности с поздним связыванием) в пользу более значимого имени?

Весь смысл сильного и статически типизированного языка заключается в устранении такого рода неоднозначности во время компиляции.