![](/img/trans.png)
[英]Using different classes with the same name as a return type in a c# webservice
[英]Method with same name and signature but different return type in C#
我接受了一次采訪,我被問到如下:
問題:具有相同名稱和簽名但返回類型不同的方法。 是否有可能,他問我這種類型是什么。
有人可以告訴我以下內容:
在任何情況下都是可能的事情(比如基類中的一個和至少派生類中的一個?)如果是這樣的類型是什么? 像編譯或運行時多態?
在編譯時多態,如果返回類型的方法也與簽名不同怎么辦? 但只有功能名稱相同。 編譯時多態還在嗎?
在覆蓋中,如果我有不同的返回類型但方法名稱和簽名相同怎么辦? 可能嗎 ? (他問我這個問題,我回答錯誤:()請幫幫我。
謝謝
它允許方法返回比在基類型中聲明的類型更多派生的類型,例如
public interface ISomeInterface { object GetValue(); } public class SomeClass : ISomeInterface { public string GetValue() { return "Hello world"; } }
這在Java中受支持,但在C#中不受支持。 由於SomeClass.GetValue
的返回類型是string
而不是object
因此上面不會編譯。
請注意,您不能僅基於return-type重載方法,即以下內容無效:
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) { }
請注意,您可以改變這些方法的返回類型 - 方法不僅可以根據它們的返回類型單獨重載,而且如果它們的參數列表不同,它們可能會有所不同。
這又是返回類型協方差,在C#中不受支持。
在C#中,你不能有類似的方法
int Foo() { return 1; }
void Foo() { return; }
它們的變化必須超過返回類型。
如果爭論不同,那么你很高興。
int Foo(string x) { return 1; }
void Foo(double x) { return; }
雖然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()
的最終結果是它將始終匹配最具體的可用類型。
是的,使用顯式接口實現可以使多個方法具有相同的簽名但返回類型不同,如下所示:
public interface I {
int foo();
}
public class C : I {
double foo() { return 2.0; }
int I.foo() { return 4; }
}
由於這是一個面試問題,你可以稍微運行一下你的答案。
嚴格地說,不可能有不同返回類型和相同簽名的方法。 但是,從廣義上講,有很多方法可以實現具體運行時返回類型不同的方法。
一個是使用通用參數。 另一個是返回具有多個實現的接口或超類。 或者,您可以返回一個可以強制轉換為任何對象的對象。
正如許多人提到的,您還可以使用“new”關鍵字在子類中返回相同方法的派生類型。
是的,您可以使用相同的方法,相同的參數(需要自定義)和不同的返回值。
只需按照以下代碼,它可能會對您有所幫助。
public class myClass
{
public int myReturn() { return 123; }
public string myReturn(string temp = null) { return "test"; }
}
問題是,它需要參數來執行函數,但是你仍然能夠忽略參數,因為你有string temp = null
作為可選參數,你仍然可以調用帶或不帶參數的函數。
我最近遇到了這個問題,因為我正在解析一個配置文件,其中包含各種類型的配置文件,這些類型都使用標准的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變量和返回是相同的,所以它有點多余,但它使我認為是一個更清潔的界面:
setting = Parse("intparam", out setting);
並且您獲得的方法僅根據返回類型而有所不同,以獲得輕微的冗余成本。 最重要的是,如果您的數據類型發生變化,例如從double變為float,那么您所有內容都將繼續正常工作,而使用第一個解決方案,您最終得到的不能隱式轉換錯誤。
您可以使用dynamic
返回類型:
你可以做whit接口
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());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.