将派生类转换为基类

我正试图刷新我的记忆但无法找到谷歌的答案。

public class BaseClass { public virtual void DoSomething() { Trace.Write("base class"); } } public class DerivedClass : BaseClass { public override void DoSomething() { Trace.Write("derived class"); } } 

如果我创建一个派生类的实例,我该如何将它转换为它的基类,这样当调用DoSomething()时,它只使用基类的方法?

动态转换仍然会调用派生类的重写方法:

 DerivedClass dc = new DerivedClass(); dc.DoSomething(); (dc as BaseClass).DoSomething(); 

输出:“派生类”

你不能 – 这完全是故意的,因为这就是多态性的全部意义所在。 假设您有一个派生类,它对您传递给重写方法的参数强制执行某些先决条件,以保持完整性……您不希望能够绕过该validation并破坏其内部完整性。

在类本身内你可以非虚拟地调用base.AnyMethod() (无论这是你要覆盖的方法还是没有)但是没关系,因为这是类本身决定可能允许其完整性被违反 – 可能它知道它是什么这样做。

虽然这听起来不合理但是有效

  DerivedClass B = new DerivedClass(); BaseClass bc = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(B)); 

你绝对可以(调用基本方法),只需阅读多态性:

http://msdn.microsoft.com/en-us/library/ms173152(v=VS.80).aspx

例:

 public class BaseClass { public void DoWork() { } public int WorkField; public int WorkProperty { get { return 0; } } } public class DerivedClass : BaseClass { public new void DoWork() { } public new int WorkField; public new int WorkProperty { get { return 0; } } } 

以及如何称呼它:

 DerivedClass B = new DerivedClass(); B.DoWork(); // This calls the new method. BaseClass A = (BaseClass)B; A.DoWork(); // This calls the old method. 

尝试使用new keywor而不是override据我所知,这应该启用所需的行为。 我不确定这一点所以如果我错了请不要怪我!

 public class BaseClass { public virtual void DoSomething() { Trace.Write("base class"); } } public class DerivedClass : BaseClass { public new void DoSomething() { Trace.Write("derived class"); } } 

使用new而不是override的解决方案打破了多态性。 最近我遇到了同样的问题并通过以下方式实现。 我的解决方案具有以下优势:

  • virtualoverride保持不变;
  • 名称BaseClass不直接在类型转换中使用,所以如果我在BaseClassDerivedClass之间的层次结构中引入一个中间的DerivedClass ,它也实现了DoSomething() ; 那么MiddleClass的实现将不会被跳过。

这是实施:

 public class BaseClass { public virtual void DoSomething() { Trace.Write("base class"); } } public class DerivedClass : BaseClass { public override void DoSomething() { Trace.Write("derived class"); } public void BaseDoSomething() { base.DoSomething(); } } 

用法是:

  DerivedClass dc = new DerivedClass(); dc.DoSomething(); dc.BaseDoSomething();