如何从基类的实例创建派生类的实例并包含私有字段?

本文关键字:实例 包含私 字段 创建 基类 派生 | 更新日期: 2023-09-27 18:17:35

我的问题与这个问题有点相关,但更具体一些。

我有一个域对象Customer,它看起来像这样:

public class Customer : Party
{
    public Identity Identity {get; protected set;}
    public bool IsOrganization {get; set;}
}

和Identity看起来像这样:

public class Identity : PersistableModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string MiddleInitial { get; set; }
    public string Title { get; set; }
    public string BusinessName { get; set; }
    public string LegalName { get; set; }
    public bool IsSynchronized { get; private set; }
}
public abstract class PersistableModel : IPersistableModel
{
    public const long UnassignedId = 0;
    public static readonly DateTime MinimumDateTime = new DateTime(1900, 1, 1);
    private readonly List<string> modifiedProperties = new List<string>();
    public virtual ModelState State { get; set; }
    public IEnumerable<string> ModifiedProperties { get { return modifiedProperties; } }
    protected bool HasModifiedProperties { get { return 0 < modifiedProperties.Count; } }
    public bool WasModified(string propertyName)
    {
        return modifiedProperties.Contains(propertyName);
    }
    public void WasModified(string propertyName, bool modified)
    {
        if (modified)
        {
            if (!WasModified(propertyName)) modifiedProperties.Add(propertyName);
        }
        else 
        {
            modifiedProperties.Remove(propertyName);
        }
    }
    public virtual void OnPersisting()
    {
    }
    public abstract void Accept(Breadcrumb breadcrumb, IModelVisitor visitor);
}

现在基于IsOrganization的值,Identity中的一些逻辑需要改变,特别是如果IsOrganization为真,个人相关字段(名字,姓氏等)需要返回null,当它为假时,组织字段需要返回null。

以前,这是通过客户的不同实现来完成的,这些实现将在它们的构造函数中将标识初始化为不同的基类,但是我正在进行的更改需要删除这两个客户类型的类分离。

我想的是让Identity属性看起来像这样:

public override Identity Identity
{
    get
    {
         if (IsOrganization)
         {
             return OrgnaizationIdentity.FromIdentity(base.Identity);
         }
         else
         {
             return IndividualIdentity.FromIdentity(base.Identity);
         }
     } 
 }

和From Identity方法看起来像这样:

public static OrgnaizationIdentity FromIdentity(Identity identity)
{
    return new OrgnaizationIdentity
    {
        FirstName = identity.FirstName,
        LastName = identity.LastName,
        MiddleNameInitial = identity.MiddleNameInitial,
        Title = identity.Title
    };
}

这里的问题是原始身份对象有一些私有字段也需要返回。

所以我的问题是,有没有一种可以接受的方法来做这样的事情?

如何从基类的实例创建派生类的实例并包含私有字段?

复制构造函数可以做到这一点,如果你可以添加和使用一个:

class Identity
{
    private int x;
    public Identity(Identity that)
    {
        this.x = that.x;
    }
}
class OrgnaizationIdentity : Identity 
{
    public OrgnaizationIdentity(Identity that) : base(that) { ... }
}

不知道为什么你不把这些属性标记为public甚至protected,如果这些真的是子类化的(我猜它们是),但这里有一个hack围绕它。

为什么不在Identity类上创建static工厂方法?这样你就能接触到身份的私人成员了?在我看来,您正在通过让其他类负责创建另一个业务对象来实现称为"贫血数据模型"的反模式。

为什么不能在你的Identity类中添加这样的东西呢?

public static Identity CreateIdentity(Customer from)
{
     Identity newId = null;
     //call other factory....
     if (from.IsOrganization)
     {
         newId =  OrgnaizationIdentity.FromIdentity(from);
     }
     else
     {
         newId = IndividualIdentity.FromIdentity(from);
     }
     //populate Identity private attribs here...
} 

这允许其他工厂方法创建子类…但允许Identity工厂看到私有变量…