我无法覆盖变量函数。比值得更好的例子,让我们举一个例子:
这是我的抽象类:
public abstract class MyClass<T> {
public abstract T DoSomething(params Object[] objs);
public void ShowSomething(List<T> items){
foreach(T it in items){
Console.WriteLine(string.Format("{0},{1},{2}",it.propA,it.propB,it.propC));
}
}
// Other things
}
这是我试图覆盖它:
public class MyOverridenClass : MyClass<MyType> {
public override MyType DoSomething(int a, int b, string c){
return new MyType(){ propA = a+b, propB = a-b, propC = c+""+a};
}
}
从我的主人那里:
public static void Main(string[] args){
MyOverridenClass cl = new MyOverridenClass();
List<MyType> lst = new List<MyType>();
lst.Add(cl.DoSomething(1,2,"foo"));
cl.ShowSomething();
}
我希望它输出:
3,-1,foo1
但是当我编译时,我有一个错误,说没有找到合适的方法来覆盖DoSomething(int,int,string)。
是否可能或者我必须找到解决方法?
谢谢!
答案 0 :(得分:3)
覆盖方法时,签名必须相同。你不能发明&#34;一个新的签名。
public override MyType DoSomething(params Object[] objs)
{
// do something
}
你在这里无能为力......
因此,您必须决定您希望方法具有哪种签名,并使用它。您甚至可以在MyClass<T>
答案 1 :(得分:1)
DoSomething
中的 MyOverriddenClass
无法覆盖DoSomething(params Object[] objs)
,因为您无法覆盖具有非可变参数的可变参数函数。
为什么不是这样的简单回答是因为规范是这样说的。但是,在一种不是C#的想象语言中,这仍然不起作用,因为实施方法不如基本方法具体,违反了合同。
在C#中,签名必须在覆盖时完全匹配,但这不是正确性所必需的。为了正确,方法实现合同就足够了。
例如,这是一个基类,它返回Base类型的东西,并将一个对象作为参数。
public class Base {
public Base example(TParam obj)
}
如果我们要覆盖示例,我们需要它更具体才能正确
public class Derived : Base {
override public TReturn example(TParam2 obj) //this is illegal in C#
}
C#需要TReturn
== Base
和TParam
== TParam2
。同时,正确性要求不那么严格。它只需要TReturn : Base
和TParam : TParam2
(请注意它们被翻转)
要了解原因,请以
为例Base b = new Derived()
Base newbase = d.example(default(TParam))
它必须返回一个符合&#34;适合&#34;在Base
。它也最需要任何可以输入Base.example
的参数。如果它需要更多特定的参数,那么你就会被软化,因为编译器不知道(并且不能知道并且不应该知道){{ 1}}类型为b
。
现在回到可变方法。可以想象,某种语言不是C#但看起来像它确实允许这样做。可以想象的是,这种不是C#的语言在分解可变方法时会有一些语法糖,而且可以来回传递以下内容:
Derived
但派生类型中的实现应始终在其参数列表中不太具体,而不是更具体。因此,这种(非C#)语言可以做的最好的就是允许你覆盖,例如,
public T Example(params object[] objs)
public T Example2(object obj1, object obj2)
与
public T Example(params SpecificType[] values)
或
public T Example(params object[] objs)
但从来没有反过来。
TL; DR:
语言不允许这样做,并且不能允许这样做,因为它会破坏替换原则。