2013-12-20 5 views
12

Я хочу копаться в том, является ли это неоднозначность или дополнительная функция, которая обеспечивается:Метод Перегрузки с другим типом возвращаемого

public class Foo 
{ 
    public int Bar(){ 
     //code 
    } 

    public string Bar(int a){ 
     //code 
    } 
} 

Любой имеющий опыт работы с этим, перегрузка на тип возвращаемого значения с различными параметры должны быть плохой практикой, не так ли?

Но если перегрузка была выполнена на основе типа возврата, то почему это не работает.

public class Foo 
{ 
    public int Bar(int a){ 
     //code 
    } 

    public string Bar(int a){ 
     //code 
    } 
} 

Как это будет не в состоянии решить, какие функции для вызова 1-й или второй, если мы называем obj.Bar(); , это должно закончиться ошибкой, если у кого-нибудь есть представление об этом, почему он позволяет запускать первый фрагмент кода.

+0

Вы можете сделать свой вопрос более ясным? Я думаю, что все неправильно поняли ваш вопрос. –

+1

@ChrisLava Какое другое возможное значение есть, кроме заданного в ответах? – Rotem

+2

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

ответ

24

C# спецификация (раздел 10.6) утверждает, что перегруженные члены не могут отличаться только возвращаемым типом и согласно http://msdn.microsoft.com/en-us/library/ms229029.aspx

По вашему вопросу о создании параметров просто для поддержки различных типов возвращения? Я лично считаю, что это ужасное решение проблемы. Обслуживание кода станет трудным, а неиспользуемые параметры - это определенный запах кода. Действительно ли этот метод необходимо перегружать в этом случае? Или он принадлежит к этому классу? Должно ли создаваться что-то еще для преобразования из одного типа возврата в другой? Все, что вам нужно попросить, вывести более идиоматическое решение.

0

C# does not allow it.

С другой стороны, C# не поддерживает разрешение метода на основе типа возврата; это было сознательное решение разработчиками языка , чтобы не раскрывать функцию CLR, которая позволяет это. Там нет техническая причина, почему они не могли этого сделать, они просто чувствовали себя лучше не. Поскольку возвращаемое значение не используется для выбора метода, Подпись метода C# не включает его.

3

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

  1. типы параметров
  2. Количество параметров
  3. Порядок параметров, объявленных в методе

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

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

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

0

Вы не можете создать метод с тем же именем, с тем же числом и типами параметров.

Для получения более подробной информации обратитесь к этому link.

13

Это логически невозможно. Рассмотрим следующий вызов:

object o = Bar(42); 

или даже

var o = Bar(42); 

Как бы компилятор знать, какой метод для вызова?

Edit: Теперь, когда я понимаю, что вы на самом деле просят, я думаю, что перегрузка бессмысленными параметров плохая практика, и снижается читаемость, гораздо предпочтительнее, чтобы отличить имя метода:

string BarToStr() 
{ 

} 

int BarToInt() 
{ 

} 
+1

Компилятор может генерировать ошибку, * если он не может решить правильную перегрузку *. Это позволит 'string foo = BarToStr()'. Дополнительную информацию см. В закрытом-дублированном ответе. –

2

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

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

Редактировать - как указывает ChrisLava, «путь вокруг этого заключается в том, чтобы иметь лучшие имена для каждой функции (вместо перегрузки). Имена, которые имеют ясное значение в приложении. Нет причин, по которым Bar должен возвращать int и string. Я мог просто вызвать ToString() в int "

+0

Точно! Это вопрос, как я понимаю. Все остальные неправильно поняли. Не их вина, хотя, потому что ОП сформулировал этот вопрос плохо. –

+0

рад, что не только я это читал! – NDJ

+2

Чтобы добавить к вашему ответу, я думаю, что это плохая практика, и путь вокруг этого состоит в том, чтобы иметь лучшие имена для каждой функции (вместо перегрузки). Имена, которые имеют четкое значение в приложении. Нет причин, по которым Bar должен возвращать int и строку. Я мог видеть только вызов ToString() в int. –

0

Проверьте это .. У вас не может быть метода с той же подписью и только с другим типом возврата. Рекомендуемый упоминается в этом вопросе.

C# Overload return type - recommended approach

0

Ваш код приведет к Compiler Error. Вы не можете иметь метод с тем же именем с теми же параметрами и другим типом возврата, вызывающий не знал бы, какой метод вызывать (не сможет разрешить местоположение в памяти метода для вызова, почему компилятор не допускайте этого). Ваша альтернатива - вернуть объект и передать его на основе того, что знает Звонок. Даже тогда это кажется плохим дизайном.

Это будет работать (что означает «Скомпилировать»), но все равно плохой дизайн.

public class Foo 
{ 
    public object Bar(int a) 
    { 
     return a; 
    } 
} 
3

Другие уже объяснили ситуацию. Я только хотел бы добавить: Вы можете делать то, что вы имеете в виду, используя параметр универсального типа:

public T Bar<T>(int a) { 
    // code 
} 

И называть это так:

int i = Bar<int>(42); 
string s = Bar<string>(42); 

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

+0

Что будет выглядеть раздел кода кода? Можете ли вы сделать оператор switch на ? – Aheho

+0

См .: http://stackoverflow.com/a/9802588/880990 –

+0

Я предполагаю, что это не сработает с не-родными типами. – Aheho

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