Перегрузка функций по типу возвращаемого значения в C #

В настоящее время я изучаю C #, и кто-то сказал мне, что действительно можно перегрузить тип, возвращаемый методами, с помощью явного ключевого слова, но он так и не объяснил, как это сделать. Я повсюду гуглил, а также читал некоторые вопросы и ответы по stackoverflow, но нигде я не нашел такого, более того, в большинстве случаев ответившие люди говорили, что невозможно перегрузить методы по типу возвращаемого значения. После всего этого я начинаю думать, что такой возможности нет. Кто-нибудь на самом деле теперь, как можно перегрузить тип, возвращаемый методом, с помощью явного ключевого слова, или это вообще возможно? Заранее спасибо.


person David_D    schedule 16.07.2014    source источник
comment
Я думаю, он говорил не о перегрузке метода, а о перегрузке оператора: msdn. microsoft.com/en-us/library/xhbhezf4.aspx   -  person Dennis_E    schedule 16.07.2014
comment
Это то, что вы ищете? stackoverflow.com/questions/15362424/   -  person Xeon    schedule 16.07.2014
comment
Он также может иметь в виду реализацию явного интерфейса, которая позволяет использовать несколько методов, различающихся только типом возвращаемого значения. Однако в строгом смысле слова это не является перегрузкой. Это перегрузка неправильно употребляемыми общими словами.   -  person quetzalcoatl    schedule 16.07.2014


Ответы (2)


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

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

Вместо этого он мог иметь в виду explicit interface implementation.

Это единственный (ну, может быть, за исключением операторов преобразования, но это несколько особые методы), который позволяет определять множество обычных методов, которые отличаются только типом возвращаемого значения. Наиболее распространенным является GetEnumerator, который раздражающе требуется как IEnumerable, так и IEnumerable<T>:

public class Foo : IEnumerable<Bar>, IEnumerable
{
    public IEnumerator<Bar> GetEnumerator() { return null; }

    // IEnumerator GetEnumerator() { return null; } // IMPOSSIBLE

    IEnumerator IEnumerable.GetEnumerator() { return null; }
}

Обратите внимание, как класс Foo определяет GetEnumerator, который возвращает универсальный итератор. Обычно сейчас невозможно определить другой GetEnumerator, который удовлетворял бы классическому IEnumeratble.

Однако с последней строкой, с явной реализацией интерфейса, это возможно. Обратите внимание, как к имени метода добавляется префикс имени интерфейса.

Также будьте осторожны: все явные реализации являются ЧАСТНЫМИ, поэтому в них нет спецификатора доступа. Это означает, что, несмотря на их успешное определение, вы не сможете перегрузить их. Явный всегда будет скрыт и никогда не будет использоваться, если вы не приведете Foo к простому IEnumerable.

So:

Foo foo = ...; // 
foo.GetEnumerator();   // calls normal typed GetEnumerator<>
((IEnumerable)foo).GetEnumerator();   // calls untyped GetEnumerator

предупреждение: правило содержится ТАКЖЕ в теле класса, что иногда может вводить в заблуждение:

public class Foo : IEnumerable<Bar>, IEnumerable
{
    public IEnumerator<Bar> GetEnumerator() { return null; }

    private void test()
    {
        // relatively obvious:

        this.GetEnumerator(); // calls GetEnumerator<>() !
        ((IEnumerable)this).GetEnumerator(); // calls plain GetEnumerator()
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        // very inobvious:

        return this.GetEnumerator(); // calls GetEnumerator<> ! no recursion!!

        // ((IEnumerable)this).GetEnumerator(); // would call itself recursively
    }
}
person quetzalcoatl    schedule 16.07.2014
comment
Большое спасибо, это было очень полезно. Я бы проголосовал, но не могу. Я спрошу этого человека позже, действительно ли он имел в виду перегрузку оператора, а не метода, возможно, он использовал неправильное слово или намеренно вызвал у меня головную боль. - person David_D; 16.07.2014
comment
Однако вы можете определить несколько методов, которые отличаются только типом возвращаемого значения --- правда? код не компилируется: static string F(int x) { return ""; } static int F(int y) { return 0; } - person Lei Yang; 27.12.2019
comment
@LeiYang: Вы пропустили очень много моего поста. Код, который вы указываете в своем комментарии, представляет собой попытку создать перегрузку, которая отличается по типу возвращаемого значения. Вы видели пример кода, который я предоставил? public class Foo и так далее? Посмотрите внимательно, что внутри этого класса. Есть даже комментарий, который отмечает перегрузку, которую вы не можете сделать, и есть два метода GetEnumerator, определенные, и эти методы имеют одно и то же имя, те же аргументы и различаются типом возвращаемого значения, и эти два метода НЕ являются перегрузками. - person quetzalcoatl; 27.12.2019
comment
привет, я не хотел вас волновать, но я ожидаю, что само предложение всегда будет правильным без другого контекста, потому что у вас так много баллов. - person Lei Yang; 27.12.2019
comment
@LeiYang: expecting the sentence itself to be always correct without other context - хорошо, я понимаю, что это может ввести в заблуждение, если не читать весь текст ответа. Я подумаю и постараюсь улучшить формулировку. (хотя человеческое общение в основном связано с контекстом :), но я понимаю вашу точку зрения :)) - person quetzalcoatl; 29.12.2019

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

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

string func(int i){return "";}
int func(int i){return 0;}

void main(){
    func(1);//what happens here??? which method gets called??
} 
person flo_badea    schedule 16.07.2014