简体   繁体   English

如何从基类方法访问派生类实例?

[英]How to access derived class instance from base class method?

My base class has a method to serialize itself that I want derived classes to use.我的基类有一个方法来序列化自己,我希望派生类使用它。

public abstract class Base
{
    public int Property1 { get; set; }

    public virtual string Serialize()
    {
       ...
       return System.Text.Json.JsonSerializer.Serialize(this, jsonSerializerOptions);
    }
}

The problem is that "this" in the base classes refers to the base class.问题是基类中的“this”指的是基类。 When calling Serialize() from derived classes, only the properties of the base class are serialized.从派生类调用 Serialize() 时,只会序列化基类的属性。 What can I use instead of "this" to pass to the Json serializer so that it will refer to the instance of the derived class.我可以使用什么代替“this”来传递给 Json 序列化程序,以便它引用派生类的实例。

Derived class may look like this:派生类可能如下所示:

public class Derived : Base
{
     public int Property2 { get; set; }
}

I then call the Serialize() method like this:然后我像这样调用 Serialize() 方法:

Derived derived = new Derived();
string json = derived.Serialize();

Only Property1 is serialized.只有 Property1 被序列化。

The reason of it serialize Property1 only is you didn't override the virtual method in the derived class, So it works only for property1.它仅序列化 Property1 的原因是您没有覆盖派生类中的虚方法,因此它仅适用于 property1。

Sample:样本:

public abstract class Base
    {
        public int Property1 { get; set; } = 20;

        public virtual void Display()
        {

            MessageBox.Show(Property1.ToString());
        }
    }
public class Derived : Base
    {
        public int Property2 { get; set; } = 9;
        public override void Display() //without this you can't achieve what you want
        {
            base.Display();
            MessageBox.Show(Property2.ToString());

        }

    }

public class Test
    {
        public void ShowResult()
        {
            Derived derived = new Derived();
            derived.Display();
        }
    }


Test test = new Test();
{
  test.ShowResult();
}

OUTPUT输出

Two Messageboxes两个消息框

First displays: 20首次展示:20

Second displays: 9第二显示器:9

If I didn't override the virtual method in the derived class the OUTPUT would be:如果我没有覆盖派生类中的虚方法,则OUTPUT将是:

One Messageboxe ONLY仅一个 Messageboxe

Displays: 20显示器:20

From Documentation文档

When a virtual method is invoked, the run-time type of the object is checked for an overriding member.当调用虚拟方法时,将检查对象的运行时类型是否有覆盖成员。 The overriding member in the most derived class is called, which might be the original member, if no derived class has overridden the member.调用最派生类中的覆盖成员,如果没有派生类覆盖该成员,则该成员可能是原始成员。

we can't change 'this' behavior, but you can try below solution, its work like what you need我们无法改变“这种”行为,但您可以尝试以下解决方案,它的工作方式与您需要的一样

    class Program
{
    static void Main(string[] args)
    {
        Derived d = new Derived();

        Console.WriteLine(d.Serialize());
        Console.ReadLine();
    }
}
public abstract class Base
{
    public int Property1 { get; set; }
}
public class Derived : Base
{
    public int Property2 { get; set; }
}

public static class Extensions
{
    public static string Serialize(this Base obj)
    {
        return System.Text.Json.JsonSerializer.Serialize((object)obj);
    }
}

The overload method you are using is Serialize< BaseClass >(this, options) .您使用的重载方法是Serialize< BaseClass >(this, options) This when called from the base class always pass the BaseType as T .当从基类调用时,它总是将BaseType作为T传递。

Fortunately, JsonSerializer provides another overload which you can use from baseclass and achieve the desired behavior without overriding in derived class.幸运的是, JsonSerializer提供了另一个重载,您可以从基类使用它并实现所需的行为,而无需覆盖派生类。 For this, You should be using Serialize(this,this.GetType(),options) .为此,您应该使用Serialize(this,this.GetType(),options) this.GetType() wil always returns the instance type even when call is done from a base class.即使从基类完成调用, this.GetType()始终返回实例类型。

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

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