在基本类型“virtual”中声明一个方法,然后在子类型中使用“override”关键字重写它,与在子类型中声明匹配的方法时简单地使用“new”关键字相比,两者之间有什么区别?
当前回答
using System;
using System.Text;
namespace OverrideAndNew
{
class Program
{
static void Main(string[] args)
{
BaseClass bc = new BaseClass();
DerivedClass dc = new DerivedClass();
BaseClass bcdc = new DerivedClass();
// The following two calls do what you would expect. They call
// the methods that are defined in BaseClass.
bc.Method1();
bc.Method2();
// Output:
// Base - Method1
// Base - Method2
// The following two calls do what you would expect. They call
// the methods that are defined in DerivedClass.
dc.Method1();
dc.Method2();
// Output:
// Derived - Method1
// Derived - Method2
// The following two calls produce different results, depending
// on whether override (Method1) or new (Method2) is used.
bcdc.Method1();
bcdc.Method2();
// Output:
// Derived - Method1
// Base - Method2
}
}
class BaseClass
{
public virtual void Method1()
{
Console.WriteLine("Base - Method1");
}
public virtual void Method2()
{
Console.WriteLine("Base - Method2");
}
}
class DerivedClass : BaseClass
{
public override void Method1()
{
Console.WriteLine("Derived - Method1");
}
public new void Method2()
{
Console.WriteLine("Derived - Method2");
}
}
}
其他回答
new关键字实际上创建了一个全新的成员,该成员只存在于该特定类型上。
例如
public class Foo
{
public bool DoSomething() { return false; }
}
public class Bar : Foo
{
public new bool DoSomething() { return true; }
}
该方法存在于这两种类型上。当您使用反射并获取Bar类型的成员时,您实际上会发现两个称为DoSomething()的方法看起来完全相同。通过使用new,你可以有效地将实现隐藏在基类中,这样当类从Bar派生出来时(在我的例子中),对base. dosomething()的方法调用就会到Bar而不是Foo。
Virtual / override告诉编译器这两个方法是相关的,在某些情况下,当你认为你在调用第一个(虚拟)方法时,实际上应该调用第二个(被重写)方法。这是多态性的基础。
(new SubClass() as BaseClass).VirtualFoo()
将调用子类的重载VirtualFoo()方法。
New告诉编译器,您正在向派生类添加与基类中的方法同名的方法,但它们之间没有关系。
(new SubClass() as BaseClass).NewBar()
将调用BaseClass的NewBar()方法,而:
(new SubClass()).NewBar()
将调用子类的NewBar()方法。
“new”关键字不会重写,它表示一个与基类方法无关的新方法。
public class Foo
{
public bool DoSomething() { return false; }
}
public class Bar : Foo
{
public new bool DoSomething() { return true; }
}
public class Test
{
public static void Main ()
{
Foo test = new Bar ();
Console.WriteLine (test.DoSomething ());
}
}
它输出false,如果你使用override,它会输出true。
(基本代码取自Joseph Daigle)
所以,如果你在做真正的多态性,你应该总是OVERRIDE。唯一需要使用“new”的地方是当方法与基类版本没有任何关联时。
using System;
using System.Text;
namespace OverrideAndNew
{
class Program
{
static void Main(string[] args)
{
BaseClass bc = new BaseClass();
DerivedClass dc = new DerivedClass();
BaseClass bcdc = new DerivedClass();
// The following two calls do what you would expect. They call
// the methods that are defined in BaseClass.
bc.Method1();
bc.Method2();
// Output:
// Base - Method1
// Base - Method2
// The following two calls do what you would expect. They call
// the methods that are defined in DerivedClass.
dc.Method1();
dc.Method2();
// Output:
// Derived - Method1
// Derived - Method2
// The following two calls produce different results, depending
// on whether override (Method1) or new (Method2) is used.
bcdc.Method1();
bcdc.Method2();
// Output:
// Derived - Method1
// Base - Method2
}
}
class BaseClass
{
public virtual void Method1()
{
Console.WriteLine("Base - Method1");
}
public virtual void Method2()
{
Console.WriteLine("Base - Method2");
}
}
class DerivedClass : BaseClass
{
public override void Method1()
{
Console.WriteLine("Derived - Method1");
}
public new void Method2()
{
Console.WriteLine("Derived - Method2");
}
}
}
new关键字用于隐藏。-意味着你在运行时隐藏你的方法。输出将基于基类方法。 Override用于重写。-表示您正在调用派生类方法引用基类。输出将基于派生类方法。
推荐文章
- 将字符串转换为System.IO.Stream
- 如何从枚举中选择一个随机值?
- 驻留在App_Code中的类不可访问
- 在链式LINQ扩展方法调用中等价于'let'关键字的代码
- dynamic (c# 4)和var之间的区别是什么?
- Visual Studio: ContextSwitchDeadlock
- 返回文件在ASP。Net Core Web API
- 自定义HttpClient请求头
- 如果我使用OWIN Startup.cs类并将所有配置移动到那里,我是否需要一个Global.asax.cs文件?
- VS2013外部构建错误"error MSB4019: The imported project <path> was not found"
- 从另一个列表id中排序一个列表
- 等待一个无效的异步方法
- 覆盖或覆盖
- 无法加载文件或程序集…参数不正确
- c#中枚举中的方法