C#中具有相同名称和签名但返回类型不同的方法

Lea*_*ner 23 .net c# polymorphism inheritance c#-4.0

我接受了一次采访,我被问到如下:

问题:具有相同名称和签名但返回类型不同的方法.是否有可能,他问我这种类型的东西.

有人可以告诉我以下内容:

  1. 在任何情况下都是可能的事情(比如基类中的一个和至少派生类中的一个?)如果是这样的类型是什么?像编译或运行时多态?

  2. 在编译时多态,如果返回类型的方法也与签名不同怎么办?但只有功能名称相同.编译时多态还在吗?

  3. 在覆盖中,如果我有不同的返回类型但方法名称和签名相同怎么办?可能吗 ?(他问我这个问题,我回答错误:()请帮帮我.

谢谢

Lee*_*Lee 36

  • 我假设问题是关于返回类型协方差

    它允许方法返回比在基类型中声明的类型更多派生的类型,例如

    public interface ISomeInterface
    {
        object GetValue();
    }
    
    public class SomeClass : ISomeInterface
    {
        public string GetValue() { return "Hello world"; }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    这在Java中受支持,但在C#中不受支持.上述将无法编译,因为的返回类型SomeClass.GetValuestring不是object.

    请注意,您不能仅基于return-type重载方法,即以下内容无效:

    public class SomeClass
    {
        public int GetValue() { return 1; }
        public string GetValue() { return "abc"; }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    您可以使用接口执行类似的操作,但您需要明确地实现它们以消除歧义:

    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; }
    }
    
    Run Code Online (Sandbox Code Playgroud)

  • 如果名称相同但参数不同,那么这就是方法重载.这是一种多态性(ad-hoc多态性).在编译类型下静态解析重载(除非您使用的是dynamic在这种情况下它们被延迟到运行时).

    您可以重载参数的数量及其类型,因此以下都是有效的:

    public void DoSomething(int value) { }
    public void DoSomething(string value) { }
    public void DoSomething(int value, string value) { }
    
    Run Code Online (Sandbox Code Playgroud)

    请注意,您可以改变这些方法的返回类型 - 方法不仅可以根据它们的返回类型单独重载,而且如果它们的参数列表不同,它们可能会有所不同.

  • 这又是返回类型协方差,在C#中不受支持.


    Tod*_*ang 10

    在C#中,你不能有类似的方法

    int Foo() { return 1; }

    void Foo() { return; }

    它们的变化必须超过返回类型.

    如果争论不同,那么你很高兴.

    int Foo(string x) { return 1; }

    void Foo(double x) { return; }


    Jea*_*nal 7

    虽然C#不支持返回类型协方差,但可以通过使用显式实现和方法隐藏来模拟它.这是在ADO.NET API中彻底使用的模式.

    例如:

    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; }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    通过这样做,调用的最终结果GetValue()是它将始终匹配最具体的可用类型.


    Pie*_*ens 6

    是的,使用显式接口实现可以使多个方法具有相同的签名但返回类型不同,如下所示:

    public interface I {
      int foo();
    }
    
    public class C : I {
      double foo() { return 2.0; }
      int I.foo() { return 4; }
    }
    
    Run Code Online (Sandbox Code Playgroud)