zfe*_*ran 83 c# overriding overloading
有没有办法覆盖非虚方法?或者给出类似结果的东西(除了创建一个新的方法来调用所需的方法)?
我想从Microsoft.Xna.Framework.Graphics.GraphicsDevice单元测试中覆盖一个方法.
And*_*are 104
不,您不能覆盖非虚方法.你可以做的最接近的事情是通过创建一个new具有相同名称的方法来隐藏方法,但这不建议,因为它打破了良好的设计原则.
但即使隐藏一个方法也不会给你执行时间多态调度方法调用就像真正的虚方法调用一样.考虑这个例子:
using System;
class Example
{
static void Main()
{
Foo f = new Foo();
f.M();
Foo b = new Bar();
b.M();
}
}
class Foo
{
public void M()
{
Console.WriteLine("Foo.M");
}
}
class Bar : Foo
{
public new void M()
{
Console.WriteLine("Bar.M");
}
}
Run Code Online (Sandbox Code Playgroud)
在此示例中,两次调用M方法都打印Foo.M.正如您所看到的,只要对该对象的引用具有正确的派生类型,但隐藏基本方法确实会破坏多态,这种方法确实允许您为方法创建一个新实现.
我建议您不要以这种方式隐藏基本方法.
我倾向于支持那些赞成C#默认行为的人,默认情况下这些方法是非虚拟的(而不是Java).我会更进一步说,默认情况下也应该密封类.继承很难正确设计,并且有一个未标记为虚拟的方法这一事实表明该方法的作者从未想过要覆盖该方法.
编辑:"执行时多态调度":
我的意思是在调用虚方法时在执行时发生的默认行为.比方说,在我之前的代码示例中,我确实定义了一个虚方法和一个真正的重写方法,而不是定义一个非虚方法.
如果我b.Foo在那种情况下调用,CLR将正确地确定b引用所指向的对象的类型,Bar并将M适当地调度该调用.
Vya*_*sky 11
您无法覆盖 C# 中任何类的非虚拟方法(无需破解 CLR),但您可以覆盖该类实现的接口的任何方法。考虑我们有非密封的
class GraphicsDevice: IGraphicsDevice {
public void DoWork() {
Console.WriteLine("GraphicsDevice.DoWork()");
}
}
// with its interface
interface IGraphicsDevice {
void DoWork();
}
// You can't just override DoWork in a child class,
// but if you replace usage of GraphicsDevice to IGraphicsDevice,
// then you can override this method (and, actually, the whole interface).
class MyDevice: GraphicsDevice, IGraphicsDevice {
public new void DoWork() {
Console.WriteLine("MyDevice.DoWork()");
base.DoWork();
}
}
Run Code Online (Sandbox Code Playgroud)
这是演示
class Program {
static void Main(string[] args) {
IGraphicsDevice real = new GraphicsDevice();
var myObj = new MyDevice();
// demo that interface override works
GraphicsDevice myCastedToBase = myObj;
IGraphicsDevice my = myCastedToBase;
// obvious
Console.WriteLine("Using real GraphicsDevice:");
real.DoWork();
// override
Console.WriteLine("Using overriden GraphicsDevice:");
my.DoWork();
}
}
Run Code Online (Sandbox Code Playgroud)