C#中具有相同名称和签名但返回类型不同的方法
Posted
技术标签:
【中文标题】C#中具有相同名称和签名但返回类型不同的方法【英文标题】:Method with same name and signature but different return type in C# 【发布时间】:2013-02-28 00:52:50 【问题描述】:我在面试中被问到以下问题:
问题:具有相同名称和签名但返回类型不同的方法。有没有可能,他问我这种类型叫什么。
谁能告诉我以下内容:
在任何情况下都可能出现上述情况(例如基类中的一个和派生类中的一个?)如果是,它是什么类型?比如编译或运行时多态?
在编译时多态中,如果方法的返回类型和签名也不同怎么办?但只有函数的名称是相同的。还是编译时多态吗?
在重写时,如果我有不同的返回类型但方法名称和签名相同怎么办?可能吗 ? (他问我这个问题,我答错了:()请帮帮我。
谢谢
【问题讨论】:
你的答案是什么,为什么? 不可能。您可以尝试以这种方式重载您的方法,但编译器不会接受。 @Oded:大声笑我才意识到我回答错了。我说过,它被称为编译时多态性,并且在同一个类中是不可能的,但是一个虚函数可以在基类中,我们可以覆盖它或在派生类中使用“new”关键字以不同的返回类型。但是如果我们把它放在同一个类中,它会给出一个错误,说两个函数有相同的名字。我在面试时没有深思熟虑,我才意识到:(哈哈这个我无法回答的简单问题,走了。我应该多做些工作。 @Nolonar:非常感谢您的回答,今晚我将在 VS 中处理所有可能的情况以很好地理解这一点......再次感谢您:) 干杯 【参考方案1】:您可以使用dynamic
返回类型:
【讨论】:
【参考方案2】:你可以在界面上做到这一点
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());
【讨论】:
【参考方案3】:我最近遇到了这个确切的问题,因为我正在解析具有各种类型的配置文件,这些类型都使用标准的 config.Parse(string settingName) 类型接口。
第一种解决方案通用方法:
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;
out 变量和 return 是相同的,所以它有点多余,但它使我认为是一个更干净的接口:
setting = Parse("intparam", out setting);
您会获得仅因返回类型不同而有所不同的方法,这会带来轻微的冗余成本。最重要的是,如果您的数据类型发生变化,例如从双精度型变为浮点型,那么您一切都将继续正常工作,而使用第一个解决方案您最终会得到无法隐式转换错误。
【讨论】:
【参考方案4】:是的,你可以使用相同的方法,相同的参数(需要自定义)和不同的返回值。
只需按照下面的代码操作,它可能会对您有所帮助。
public class myClass
public int myReturn() return 123;
public string myReturn(string temp = null) return "test";
问题是,它需要参数来执行函数,但你仍然可以忽略参数,因为你有 string temp = null
作为可选参数,也就是说你仍然调用带有或不带参数的函数。
【讨论】:
我不这么认为,它不会用“var x = myReturn();”编译【参考方案5】:在 C# 中,你不能拥有像
这样的方法int Foo() return 1;
void Foo() return;
它们的变化必须超过返回类型。
如果参数不同,那么你就可以开始了。
int Foo(string x) return 1;
void Foo(double x) return;
【讨论】:
这完全让我明白了,非常感谢:) 干杯 顺便说一句,我在这里根本看不到多态性,但我没有参加你的采访。 :) 真正快速的多态性就像 void Foo(Animal a).. 和 class Dog : Animal。你用狗而不是动物来调用 Foo(aDog)。多态性将您的派生类型(Dog)神奇地转换为基本类型(Animal)。更多关于多态性的信息:codeproject.com/Articles/4839/Building-Snap-In-Applications 再次感谢托德,不知怎的,很多事情对我来说都是新事物,因为我已经 3 个月没有接触了。同样,我是一个初学者(我有大约 2 年的经验,还有很多东西要学)...谢谢 :) 我正在浏览这个 codeproject 链接 :) 干杯【参考方案6】:由于这是一个面试问题,你可以稍微回答一下。
严格来说,不同返回类型和相同签名的方法是不可能的。但是,从广义上讲,有很多方法可以实现具体运行时返回类型不同的方法。
一个是使用泛型参数。另一个是返回具有多个实现的接口或超类。或者,您可以返回一个可以转换为任何东西的对象。
正如许多人提到的,您还可以使用“new”关键字在子类中返回相同方法的派生类型。
【讨论】:
感谢 gabnaim 的回答,这对我有帮助:)【参考方案7】: 我认为问题是关于return type covariance它允许方法返回比在基类型中声明的类型更派生的类型,例如
public interface ISomeInterface
object GetValue();
public class SomeClass : ISomeInterface
public string GetValue() return "Hello world";
这在 Java 中受支持,但在 C# 中不受支持。以上将无法编译,因为SomeClass.GetValue
的返回类型是string
而不是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 polymorphism)。重载在 compile-type 静态解析(除非您使用 dynamic
在这种情况下它们被推迟到运行时)。
你可以重载参数的数量和它们的类型,所以以下都是有效的:
public void DoSomething(int value)
public void DoSomething(string value)
public void DoSomething(int value, string value)
请注意,您可以更改这些方法的返回类型 - 方法不能仅根据其返回类型重载,但如果它们的参数列表不同,它们可能会有所不同。
这又是返回类型协方差,在 C# 中不受支持。
【讨论】:
谢谢,但在第二个问题中,我很想知道,当我们说方法重载时。就像,我们应该首先为方法使用相同的名称?其次,我们应该通过数字或类型来改变参数?最后我应该有相同的返回类型吗?否则程序根本无法编译,这就是你的意思吗? C# 中没有任何概念吗? @Divine - 重载时方法名称必须相同,但参数列表必须不同。它们的类型和/或参数数量可能不同。不需要具有相同的返回类型,只是重载解析仅对方法的参数进行,而不是返回类型。这意味着方法不能仅在其返回类型上被重载。我已经用这些信息更新了答案。 C# 确实允许方法重载,但不允许基于返回类型重载方法,并且不允许返回类型协变。 非常感谢,正如托德所说, public int DoSomething(string value) public void DoSomething(int value, string value) 我可以这样吗?没问题 ?但是我知道它不会超载【参考方案8】:虽然 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()
的最终结果是它将始终匹配最具体的可用类型。
【讨论】:
感谢 Jean 向我解释,这对我有帮助 :) 干杯【参考方案9】:是的,可以有多个具有相同签名但返回类型不同的方法,使用如下所示的显式接口实现:
public interface I
int foo();
public class C : I
double foo() return 2.0;
int I.foo() return 4;
【讨论】:
以上是关于C#中具有相同名称和签名但返回类型不同的方法的主要内容,如果未能解决你的问题,请参考以下文章