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

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

2 ответа

Решение

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

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.

Так:

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
    }
}

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

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

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

void main(){
    func(1);//what happens here??? which method gets called??
} 
Другие вопросы по тегам