当前位置: 首页 > 知识库问答 >
问题:

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

曹高轩
2023-03-14

我在一次面试中被问到以下问题:

问题:名称和签名相同但返回类型不同的方法。他问我,可能吗?这种类型叫什么。

有人能告诉我以下情况吗:

>

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

    在编译时多态性中,如果方法的返回类型与签名也不同,该怎么办?但只有函数的名称是相同的。还是编译时多态性吗?

    在重写中,如果我有不同的返回类型,但方法名和签名相同,该怎么办?可能吗?他问我这个问题,我回答错了:()请帮帮我。

    谢谢你

  • 共有3个答案

    穆子琪
    2023-03-14

    虽然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; }
    }
    

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

    桓瀚
    2023-03-14

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

    int Foo(){返回1;}

    无效Foo(){返回;}

    它们的差异必须大于返回类型。

    如果论点不同,那么你就可以走了。

    int Foo(字符串x){返回1;}

    void Foo(双x){return;}

    黄仲渊
    2023-03-14

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

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

    这在Java中支持,但在C#中不支持。上面的代码将不会编译,因为返回的类型是某些类。GetValue字符串而不是对象

    请注意,不能仅基于返回类型重载方法,即以下内容无效:

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

    您可以使用接口做类似的事情,尽管您需要显式地实现它们来消除歧义:

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

    如果名称相同,但参数不同,则这是方法重载。这是多态性的一种形式(即席多态性)。重载在编译类型中静态解决(除非您使用的是动态重载,在这种情况下,重载将推迟到运行时)。

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

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

    请注意,您可以改变这些方法的返回类型-方法不能仅基于其返回类型而重载,但如果其参数列表不同,则它们可以不同。

    同样,这是返回类型协方差,在C#中不受支持。

     类似资料:
    • 问题内容: 以下代码可以正常工作。在两个不同的结构上操作并打印该结构的字段的两种方法: 在控制台中显示所需的输出: 现在 ,如果我以以下方式更改方法签名,则会出现编译错误。我只是将方法的接收者移动到方法的参数: 我什至无法编译程序: 问 :为什么 当 方法具有相同的名称和Arity 时 ,我可以在接收器中互换结构类型,而不能在参数中互换结构类型? 问题答案: 因为Go不支持在其参数类型上重载用户定

    • 我可以看到它不工作,因为我尝试了它。我只是无法解释为什么一定要这样。 第二个方法来自一个类,该类是实现第一个getValue()方法的类的子类。 为什么同名不足以覆盖该方法?我想到的唯一论点是,它将反对“是一个”关系,因为用A扩展的第二个方法的类必须具有与A相同的能力,如果你重写返回类型,你就打破了那个法律,对吧?

    • 我说的是Java,但这个概念也适用于其他语言-- 我们在同一个类上有两个方法,它们具有相同的基本功能,但提供不同的返回类型。这两种方法都会给你所有的东西,但一个得到一个可以提供对所有东西的访问的可迭代的,一个得到一个包含所有东西的集合。 我们知道你不能这样做(因为它不会编译): 那么,有人想过如何命名这些方法吗?这似乎是一个简单的解决方法: 然而,这显然有些冗长,可能不是最好的解决方案。我问的这个

    • 问题内容: 我有一个Animal类和一个名为AnimalExtension的Animal扩展。 这两个类之间的唯一区别是AnimalExtension还有另一个实例变量叫做animalId。Animal没有此实例变量。 我也有自己的数据类型,想要对XML进行封送处理。此数据类型称为AnimalList。在AnimalList内,有一个Animals列表作为实例变量。 animalList可以包含A

    • 问题内容: 我在这里已经读到,在Java中,具有相同名称但不同类型的两个变量可以在同一范围内共存。我的意思是这个 但是所有的Java IDE都不允许这样的代码。我想知道这样的代码在语法上是否正确,或者只是IDE不允许这样的代码防止歧义。 无论如何,这是网站的摘录 “如果幸运的话,您也许能够重新编译Jad的输出。 但是,Java VM对于变量命名的规则比Java语言本身更为宽松。例如,一个有效的类文

    • 但所有java IDE都不允许这样的代码。我想知道这样的代码在语法上是否真的正确,或者只是IDE不允许这样的代码来防止歧义。 总之,这里是从网站上摘录的 “如果你幸运的话,你也许可以重新编译JAD的输出。然而,Java VM对变量命名的规则比Java语言本身更宽松。例如,一个有效的类文件可以有几个名为'a'的变量,只要它们有不同的类型。如果你反编译这样的类,你得到的源代码将是无效的。 JAD通常会