我无法覆盖可变函数。比单词更有价值的示例,让我们举一个示例:
这是我的抽象课:
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)。
甚至有可能还是我必须找到一种解决方法?
谢谢 !
DoSomething
inMyOverriddenClass
无法覆盖,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
。同时,正确性要求宽松一些。它仅需要thatTReturn : Base
和that TParam : TParam2
(请注意,它们已翻转)
要了解原因,举个例子
Base b = new Derived()
Base newbase = d.example(default(TParam))
它必须返回一个将“适合”的值Base
。它也大多数采用可以馈入的任何参数Base.example
。如果它需要更具体的参数,那么您就被束之高阁,因为编译器不知道(也不应该也不应该知道)那个b
type Derived
。
现在回到可变参数方法。可以想象,某些非C#语言的语言确实允许这种情况。同样可以想象的是,这种不是C#的语言具有用于分解可变参数方法的某种语法糖,并且可以来回转换以下内容:
public T Example(params object[] objs)
public T Example2(object obj1, object obj2)
但是派生类型的实现在其参数列表中应始终不那么具体,而应更加具体。因此,这种(非C#)语言可以做的最好的事情就是让您覆盖,例如,
public T Example(params SpecificType[] values)
和
public T Example(params object[] objs)
或者
public T Example2(object obj1, object obj2)
但别无所求。
tl; dr:
该语言不允许这样做,也不允许这样做,因为这会破坏替代原则。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句