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

时间:2014-08-12 16:50:50

标签: c# inheritance

我的问题与this question有点相关,但有点具体。

我有一个域对象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为true,则个别相关字段(名字,姓氏等)需要返回null,当它为false时,组织需要字段需要返回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
    };
}

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

所以我的问题是,有没有一种可以接受的做法呢?

2 个答案:

答案 0 :(得分:4)

复制构造函数可以执行此操作,如果您可以添加并使用一个:

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

class OrgnaizationIdentity : Identity 
{
    public OrgnaizationIdentity(Identity that) : base(that) { ... }
}

答案 1 :(得分:1)

不确定为什么你不会将attribs标记为public甚至protected如果它们是真正的子类(我猜他们是),但这里有一个黑客攻击。< / p>

为什么不在static课程上创建Identity工厂方法?这样你就可以访问身份的私人成员了吗?在我看来,你正在通过让其他类负责创建另一个业务对象来实现称为“贫血数据模型”的反模式。

为什么不能在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工厂查看私有变量...