C#类的奇怪继承问题

Dmi*_*try 0 .net c# inheritance properties

public class DTOa
{
    public int Id { get; set;}
    public string FirstName { get; set;}
}

public class DTOb: DTOa
{
    public string Email { get; set;}
    public string Password { get; set; }
}

public class a
{
    protected DTOa _DTO = new DTOa();
    public int Id
    {
        get
        {
            return _DTO.Id;
        }
        set
        {
            _DTO.Id = value;
        }
    }

    public string FirstName
    {
        get
        {
            return _DTO.FirstName;
        }
        set
        {
            _DTO.FirstName = value;
        }
    }

    public DTOa ToValueObject()
    {
        return _DTO;
    }
}

public class b: a
{
    protected DTOb _DTO = new DTOb();

    public string Email
    {
        get
        {
            return _DTO.Email;
        }

        set
        {
            _DTO.Email = value;
        }
    }

     public string Password
    {
        get
        {
            return _DTO.Password;
        }

        set
        {
            _DTO.Password  = value;
        }
    }

    public DTOb ToValueObject()
    {
        return _DTO;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在让我们执行以下代码

public function test() 
{       
   var a = new a();
   var b = new b();
   b.Id = 100;
   b.FirstName = "Jim";
   b.Email = "email@email.com";
   b.Password = "test";
   Console.WriteLine(b.ToValueObject().Dump());
}
Run Code Online (Sandbox Code Playgroud)

问题是

  1. 我希望b.ToValueObject具有所有属性设置,但实际上只从DTOb类获取属性(所以我的FirstName和Id属性为NULL,但我明确设置)

    dump:
    {
            Email: email@email.com,
            Password: test,
            Id: 0
    }
    
    Run Code Online (Sandbox Code Playgroud)

任何想法为什么没有设置ID和FirstName没有设置?DTOb继承自DTOa,因此"应该"包含来自DTOa的所有属性.它在代码级别上工作,所以如果我写 console.WriteLine(b.Firstname)- 我会得到正确的值,但是当我调用ToValueObject()方法时 - 它被删除了.


好的,这是工作的例子:

public class DTOa : IDTO
{
    public int Id { get; set; }
    public string FirstName { get; set; }
}

public class DTOb : DTOa, IDTO
{

    public string Email { get; set; }
    public string Password { get; set; }
}

public class a
{
    protected IDTO _DTO;

    public a()
    {
        _DTO = new DTOa();
    }

    public int Id
    {
        get
        {
            return (_DTO as DTOa).Id;
        }
        set
        {
            (_DTO as DTOa).Id = value;
        }
    }

    public string FirstName
    {
        get
        {
            return (_DTO as DTOa).FirstName;
        }
        set
        {
            (_DTO as DTOa).FirstName = value;
        }
    }

    public DTOa ToValueObject()
    {
        return (_DTO as DTOa);
    }

}

public class b : a
{
    public b()
    {
        _DTO = new DTOb();
    }

    public string Email
    {
        get
        {
            return (_DTO as DTOb).Email;
        }

        set
        {
            (_DTO as DTOb).Email = value;
        }
    }

    public string Password
    {
        get
        {
            return (_DTO as DTOb).Password;
        }

        set
        {
            (_DTO as DTOb).Password = value;
        }
    }

    public DTOb ToValueObject()
    {
        return _DTO as DTOb;
    }
}
Run Code Online (Sandbox Code Playgroud)

Dea*_*ing 6

DTOb继承自DTOa,因此"应该"包含来自DTOa的所有属性

这是事实,但你也有:

public class a
{
    protected DTOa _DTO = new DTOa();
    ...
}

public class b
{
    protected DTOb _DTO = new DTOb();
    ...
}
Run Code Online (Sandbox Code Playgroud)

也就是说,类ab正在使用"DTO"类的不同实例.事实上,你的编译器应该给你一个警告_DTOb"藏"的_DTO现场a.

您要做的是确保两个类都访问同一个实例.你不能覆盖字段,但你可以覆盖方法,所以这样的东西可能是合适的:

class A
{
    private DTOa _dto = new DTOa();
    protected virtual DTOa GetDTO()
    {
        return _dto;
    }

    public string FirstName
    {
        get { return GetDTO().FirstName; }
        set { GetDTO().FirstName = value; }
    }

    ...
}

class B : A
{
    private DTOb _dto = new DTOb();
    protected virtual DTOa GetDTO()
    {
        return _dto;
    }

    public string Email
    {
        get { return GetDTO().Email; }
        set { GetDTO().Email = value; }
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

说实话,我不太确定这个"DTO"对象的好处是什么,但上面应该给你你所追求的行为.