在基本类型“virtual”中声明一个方法,然后在子类型中使用“override”关键字重写它,与在子类型中声明匹配的方法时简单地使用“new”关键字相比,两者之间有什么区别?
当前回答
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。
其他回答
我总是觉得这样的事情用图片更容易理解:
再一次,用joseph daigle的密码,
public class Foo
{
public /*virtual*/ bool DoSomething() { return false; }
}
public class Bar : Foo
{
public /*override or new*/ bool DoSomething() { return true; }
}
如果你像这样调用代码:
Foo a = new Bar();
a.DoSomething();
注意:重要的是,我们的对象实际上是一个Bar,但我们将它存储在类型为Foo的变量中(这类似于强制转换它)。
那么结果将如下所示,这取决于您在声明类时使用的是virtual/override还是new。
Beyond just the technical details, I think using virtual/override communicates a lot of semantic information on the design. When you declare a method virtual, you indicate that you expect that implementing classes may want to provide their own, non-default implementations. Omitting this in a base class, likewise, declares the expectation that the default method ought to suffice for all implementing classes. Similarly, one can use abstract declarations to force implementing classes to provide their own implementation. Again, I think this communicates a lot about how the programmer expects the code to be used. If I were writing both the base and implementing classes and found myself using new I'd seriously rethink the decision not to make the method virtual in the parent and declare my intent specifically.
下面是一些代码来理解虚拟方法和非虚拟方法行为的区别:
class A
{
public void foo()
{
Console.WriteLine("A::foo()");
}
public virtual void bar()
{
Console.WriteLine("A::bar()");
}
}
class B : A
{
public new void foo()
{
Console.WriteLine("B::foo()");
}
public override void bar()
{
Console.WriteLine("B::bar()");
}
}
class Program
{
static int Main(string[] args)
{
B b = new B();
A a = b;
a.foo(); // Prints A::foo
b.foo(); // Prints B::foo
a.bar(); // Prints B::bar
b.bar(); // Prints B::bar
return 0;
}
}
override关键字和new关键字之间的区别在于前者执行方法覆盖,后者执行方法隐藏。
查看以下链接获取更多信息…
MSDN及其他
我的解释来自于使用属性来帮助理解差异。
重写很简单,对吧?底层类型覆盖父类型。
新可能是误导(对我来说是)。使用属性更容易理解:
public class Foo
{
public bool GetSomething => false;
}
public class Bar : Foo
{
public new bool GetSomething => true;
}
public static void Main(string[] args)
{
Foo foo = new Bar();
Console.WriteLine(foo.GetSomething);
Bar bar = new Bar();
Console.WriteLine(bar.GetSomething);
}
使用调试器,你可以注意到Foo Foo有两个GetSomething属性,因为它实际上有两个版本的属性,Foo's和Bar's,为了知道使用哪个,c#“选择”当前类型的属性。
如果你想使用Bar的版本,你应该使用override或使用Foo Foo代替。
Bar Bar只有1,因为它想要GetSomething的全新行为。
推荐文章
- c#:如何获得一个字符串的第一个字符?
- String类中的什么方法只返回前N个字符?
- 更好的方法将对象转换为int类型
- 我可以将c#字符串值转换为转义字符串文字吗?
- 在c#中转换char到int
- c#中朋友的对等物是什么?
- 关键字使用virtual+override vs. new
- 在ASP中选择Tag Helper。NET Core MVC
- 如何在没有任何错误或警告的情况下找到构建失败的原因
- 跨线程操作无效:控件“textBox1”从创建它的线程以外的线程访问
- 否ConcurrentList<T>在。net 4.0?
- 在c#中解析字符串为日期时间
- 由Jon Skeet撰写的《Singleton》澄清
- 自定义数字格式字符串始终显示符号
- 单元测试无效方法?