简体   繁体   English

将派生类转换为基类

[英]Convert derived class to base class

I'm trying to refresh my memory but can't find answers with Google.我试图刷新我的记忆,但无法通过 Google 找到答案。

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

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

If I create an instance of derived class, how do I convert it to it's base class so that when DoSomething() is called, it uses the base class's method only?如果我创建派生类的实例,如何将其转换为它的基类,以便在调用 DoSomething() 时,它仅使用基类的方法?

A dynamic cast still calls the derived class's overridden method:动态转换仍然调用派生类的重写方法:

DerivedClass dc = new DerivedClass();

dc.DoSomething();

(dc as BaseClass).DoSomething();

Output: "derived class"输出:“派生类”

Although this sounds irrational but it works虽然这听起来不合理但确实有效

 DerivedClass B = new DerivedClass();

BaseClass bc = JsonConvert.DeserializeObject<BaseClass>(JsonConvert.SerializeObject(B));

You can't - that's entirely deliberate, as that's what polymorphism is all about.你不能 - 这完全是故意的,因为这就是多态性的全部内容。 Suppose you have a derived class which enforces certain preconditions on the arguments you pass to an overridden method, in order to maintain integrity... you don't want to be able to bypass that validation and corrupt its internal integrity.假设您有一个派生类,它对传递给重写方法的参数强制执行某些先决条件,以保持完整性……您不希望能够绕过该验证并破坏其内部完整性。

Within the class itself you can non-virtually call base.AnyMethod() (whether that's the method you're overriding or not) but that's okay because that's the class itself deciding to potentially allow its integrity to be violated - presumably it knows what it's doing.在类本身内,您可以非虚拟地调用base.AnyMethod() (无论是否是您要覆盖的方法),但这没关系,因为这是类本身决定可能允许其完整性受到侵犯的类 - 大概它知道它是什么正在做。

You absolutely CAN (call the base method), just read up on Polymorphism:您绝对可以(调用基本方法),只需阅读多态:

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/polymorphism https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/polymorphism

Example:例子:

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; }
    }
}

And how to call it:以及如何称呼它:

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

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

Try using the new keywor instead of override As far as i know this should enable that desired behavior.尝试使用new关键字而不是override据我所知,这应该会启用所需的行为。 I'm not realy sure about that so please don't blame me if i'm wrong!我不太确定,所以如果我错了,请不要怪我!

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

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

The solutions with new instead of override break the polymorphism.使用new而不是override的解决方案打破了多态性。 Recently I came to the same problem and implemented it the following way.最近我遇到了同样的问题并通过以下方式实现了它。 My solution has the following advantages:我的解决方案有以下优点:

  • virtual and override stays in place; virtualoverride保持原位;
  • name BaseClass is not used directly in the type cast, so if I introduce an intermediate MiddleClass in the hierarchy between BaseClass and DerivedClass , which also implements DoSomething() ;BaseClass未在铸型直接使用,因此,如果我介绍的中间MiddleClass在之间的层次结构BaseClassDerivedClass ,这也实现了DoSomething() ; then the MiddleClass 's implementation won't be skipped.那么MiddleClass的实现将不会被跳过。

This is the implementation:这是实现:

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();
    }
}

The usage is:用法是:

    DerivedClass dc = new DerivedClass();

    dc.DoSomething();

    dc.BaseDoSomething();

For VB.net, I've used the following code to do the conversion (shown with Lists of Objects):对于 VB.net,我使用以下代码进行转换(显示为对象列表):

        Dim tempPartialList As New List(Of clsBaseData)

        For Each iterClsDerivedData As clsDerivedData In ListOfDerivedDataObjects
            tempPartialList.Add(CType(iterClsDerivedData, clsBaseData))
        Next

Where clsBaseData is the Base Class from which clsDerivedData is made by Inheriting clsBaseData.其中 clsBaseData 是通过继承 clsBaseData 生成 clsDerivedData 的基类。

ListOfDerivedDataObjects is a List(Of clsDerivedData). ListOfDerivedDataObjects 是一个 List(Of clsDerivedData)。

I have found this useful where I have Lists of several Derived Classes and I would like to operate on a property of the Base Class for all the objects in the Lists of Derived Classes.我发现这在我有多个派生类列表的情况下很有用,并且我想对派生类列表中的所有对象的基类的属性进行操作。 The tempPartialList is, for me, a temporary List meant to facilitate changing this property. tempPartialList 对我来说是一个临时列表,旨在方便更改此属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM