c#虚方法覆盖返回类型&方法参数
本文关键字:方法 参数 返回类型 覆盖 | 更新日期: 2023-09-27 17:50:52
我想在抽象类中初始化具有确切名称的虚拟方法。
在class中,这是一个继承重写方法这样,我可以重写:
- 基方法返回类型
- 方法的参数
为了告诉你,我真正想做的是这样的:
abstract class A
{
public virtual void Func1() { }
}
class B : A
{
override string Func1(int a, int b)
{
return (a + b).ToString();
}
}
我知道,c#需要使用返回类型/args作为基类,但也许有一些提示关键字new
在这种情况下?
您只能override
确切的名称和参数。你可以new
任何你想要的,但这不是覆盖-只是隐藏在一个完全匹配的情况下。
我想在你的情况下,你要么想为所有可能的组合创建重载,要么创建一个基本的抽象方法,它接受一个可以包含你想要的参数的单一类型。
的例子:
public abstract void Func1( MyArgumentsType input );
现在派生类被强制覆盖一个方法,但你可以传递一组健壮的参数给方法,可以处理更多的场景。
多态性在这里对您有利,因为您可以将派生的参数类型传递给具有特定情况属性的方法。当然,这需要实现方法理解更派生的参数类型。
方法重写意味着修改继承成员的虚实现,而不是修改其签名。正如您所指出的,new
关键字将隐藏同名成员的基类实现。然而,这只是可选的,看看在与基类成员同名的派生类成员
好处
看起来您想要实现类似于ToString
方法的行为,对于不同类型(如.ToString()
和float.ToString("c")
)有许多不同的风格。
在这种情况下,ToString
的不同实现不是Object.ToString
的实现,而是基于参数适当解析的派生对象上的普通附加方法。所有的派生类最终都有一个虚拟的ToString
方法(来自基类并可能在当前类中实现)和其他可选的类似命名的非虚拟方法。
请注意,在c#中,结果类型更新考虑了函数解析时间,所以你不可能真正有两个具有相同名称和相同参数的函数,并期望其中一个被"正确"选择。如果两者同时可见,则会得到编译时错误。方法前面的new
关键字使得只有该方法对该类(和派生类)可见,并隐藏具有相同签名的基类方法。不幸的是,这样做几乎保证了很多混乱,当一个人使用基类的变量持有派生类调用这个方法-从基类的虚的一个将被调用,尽管所有的努力隐藏一个。
你不能这么做。重写方法需要具有完全相同的签名,其中包括参数和返回类型。你没有办法告诉编译器用不同的参数和返回类型覆盖一个方法。
如果你想要多态行为,你需要有兼容的签名。否则,编译器不能保证将以多态方式找到所需的方法。没有可靠的方法将签名void Func1()
和string Func1(int a, int b)
视为多态的。您可以使用内部传递lambda的out
参数泛化它们,但无论如何-要利用多态行为,您需要将它们带到一个公共签名中。
想想看…它将如何运作?假设您有一个引用,其静态类型是A
,但动态类型是B
,如下所示:
foo(B b) { bar(b); }
bar(A a) {
}
重写背后的思想是,你在super/base上调用一个方法,它会解析到被重写的实现。根据这个逻辑,你应该能够在bar
中调用a.Func1()
,它应该调用B
中的方法:
a.Func1(???)
但是这里不可能,因为缺少参数
有参数逆变和返回类型协方差的概念;这里有一个有趣的答案,链接到Eric Lippert的一篇文章,应该是一个有趣的阅读。