Подтвердить что ты не робот

Метод с тем же именем и сигнатурой, но возвращаемый тип в С#

У меня было интервью, где меня спросили следующее:

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

Может кто-нибудь скажет мне следующее:

  • Возможно ли это в любых сценариях (как в базовом классе, так и в производном классе по крайней мере?) Если да, то какой это тип? Как полиморфизм компиляции или времени выполнения?

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

  • В переопределении, что, если у меня есть другой тип возврата, но имя метода и подпись такие же? Является ли это возможным? (Он задал мне этот вопрос, я ответил не так:() Пожалуйста, помогите мне.

Спасибо

4b9b3361

Ответ 1

Я предполагаю, что речь идет о ковариации возвращаемого типа

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

public interface ISomeInterface
{
    object GetValue();
}

public class SomeClass : ISomeInterface
{
    public string GetValue() { return "Hello world"; }
}

Это поддерживается в Java, но не в С#. Вышеупомянутое не будет компилироваться, так как тип возврата SomeClass.GetValue равен string not object.

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

public class SomeClass
{
    public int GetValue() { return 1; }
    public string GetValue() { return "abc"; }
}

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

public interface IValue<T> { T GetValue(); }
public class SomeClass : IValue<int>, IValue<string>
{
    string IValue<string>.GetValue() { return "abc"; }
    int IValue<int>.GetValue() { return 1; }
}

Если имена совпадают, но параметры разные, это перегрузка метода. Это форма полиморфизма (ad-hoc-полиморфизм). Перегрузки разрешаются статически при компиляции (если вы не используете dynamic, в этом случае они отложены до времени выполнения).

Вы можете перегружать как количество параметров, так и их тип, поэтому все допустимы:

public void DoSomething(int value) { }
public void DoSomething(string value) { }
public void DoSomething(int value, string value) { }

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

Опять же, это ковариация типа возврата и не поддерживается в С#.

Ответ 2

В С# у вас не могут быть такие методы, как

int Foo() { return 1; }

void Foo() { return; }

Они должны отличаться от типа возврата.

Если аргументы разные, тогда вам хорошо идти.

int Foo(string x) { return 1; }

void Foo(double x) { return; }

Ответ 3

Хотя ковариация типа возврата не поддерживается в С#, ее можно эмулировать с помощью явной реализации и скрытия метода. Это шаблон, который полностью используется в API ADO.NET.

например:.

public interface ISomeValue { }
public abstract class SomeValueBase : ISomeValue { }
public class SomeValueImpl : SomeValueBase { }

public interface ISomeObject { ISomeValue GetValue(); }

public abstract class SomeObjectBase : ISomeObject
{
    ISomeValue ISomeObject.GetValue() { return GetValue(); }
    public SomeValueBase GetValue() { return GetValueImpl(); }

    protected abstract SomeValueBase GetValueImpl();
}

public class SomeObjectImpl : SomeObjectBase
{
    protected override SomeValueBase GetValueImpl() { return GetValue(); }
    public new SomeValueImpl GetValue() { return null; }
}

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

Ответ 4

Да, возможно иметь несколько методов с одной и той же сигнатурой, но с разными типами возвращаемых данных, используя реализацию Явного Интерфейса, как показано ниже:

public interface I {
  int foo();
}

public class C : I {
  double foo() { return 2.0; }
  int I.foo() { return 4; }
}

Ответ 5

Так как это вопрос интервью, вы можете немного поговорить с ним.

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

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

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

Ответ 6

да, вы можете использовать один и тот же метод, те же параметры (необходимо настроить) и разные возвращаемые значения.

Просто следуйте приведенным ниже кодам, это может вам помочь.

public class myClass
{
    public int myReturn() { return 123; }
    public string myReturn(string temp = null) { return "test"; }
}

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

Ответ 7

Недавно у меня была эта точная проблема, так как я разбирал конфигурационный файл с различными типами, которые используют стандартный тип интерфейса config.Parse(string settingName).

1-й общий метод решения:

T Parse<T> (string settingName)
{
    T Result;
    doParsing...
    return T;
}

Мне это не понравилось, поскольку он явно указывал тип используемого типа someSetting = Parse<float>("param");

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

T Parse<T> (string settingName, out T result)
{
    doParsing...
    return T;
}

Выходная переменная и возврат идентичны, поэтому она немного избыточна, но она обеспечивает то, что я считаю намного более понятным интерфейсом:

setting = Parse("intparam", out setting);

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

Ответ 9

Вы можете сделать это с интерфейсом

   public interface IMyInterface
{
    int Metoda1()enter code here`;
}
public class MyClass : test.IMyInterface
{
    public IMyInterface Metoda1()
    {
        return new MyClas();
    }
    int test.IMyInterface.Metoda1()
    {
        return 1;
    }
}
   static void Main(string[] args)
    {
        MyClass instance = new MyClass();
        IMyInterface inst = instance.Metoda1();
     /*   IMyInterface ints2 = inst.Metoda1(); //will not compile*/
        Console.WriteLine(inst.GetType().ToString()); ;
        object inst3 = inst.Metoda1();
        Console.WriteLine(inst3.GetType().ToString());
    }