【问题标题】:Inherited class references base class' values继承的类引用基类的值
【发布时间】:2015-07-22 22:17:19
【问题描述】:
public class ParentClass
{
    public int myId;
    public string commonField1;
    public string commonField2;
    public string commonField3;
    public string changeable;
    public List<ChildClass> children;

    public ParentClass(int id)
    {
        myId = myId;
    }

    public createChildren()
    {
        for(int i = 0; i < 999999; i++) 
        {
            children.Add(new ChildClass(id));
        }
    }
}

public class ChildClass : ParentClass
{
    public ChildClass(int id) : base (id) 
    {
        myId = myId;
        changeable = "new";
    }
}

因为ChildClass 只存在于它的ParentClass 的上下文中,并且会有999999 个孩子。那是创建所有commonField999999 副本,而实际上它只需要对其父级的引用。除了引用之外,ChildClass 唯一需要存储的是changeable

如何做到这一点?

当我需要孩子时,我几乎在想一种更好的方法,就是制作 999999 个 ParentClass 的浅拷贝,然后更改 999999 个可变字段。浅拷贝将引用commonField1 还是深拷贝值?

【问题讨论】:

  • 听起来你根本不应该使用继承。听起来孩子并不是真正的父母——它只需要一个对父母的reference。你为什么首先让 Child 扩展 Parent ? changeable 是否需要在 Parent 中?我们目前确实没有足够的上下文来建议其他代码...
  • 是的 changeable 需要在 Parent
  • 不清楚您要完成什么。如果您只使用两个公共字段,为什么ChildClass 派生自ParentClass。您不应该从只包含公共字段的公共接口或基类派生吗?我认为您混淆了包装和继承。
  • 我已经了解了基类/派生类而不是接口(还)。谷歌界面,看看是否更好
  • 如果ChildClass 真的“是”ParentClass 那么它也会有一个孩子列表,每个孩子都有一个孩子列表,等等. 我同意继承似乎不是正确的解决方案。

标签: c# class inheritance


【解决方案1】:

你说对了,如果commonFieldX 真的没有变化,那就是很多重复数据。

我看到了几种解决方案:

  1. 组合优于继承

    你为什么要继承?如果没有多态行为,那么只需将基类实例传递给 10000 个孩子并称其为好:

    public createChildren()
    {
        for(int i = 0; i < 999999; i++) {
             children.Add(new ChildClass(id, this));
        }
    }
    
    public class ChildClass
    {
         public ChildClass(int id, ParentClass parent) : base (id) 
         {
               myId = myId; //This shouldn't be part of the base class?
               changeable = "new"; //Same here
               myParent = parent;
         }
    }
    
  2. 在所有实例之间共享这些变量

    static 成员属于“全局”实例,因此不会为每个派生对象重新创建它们:

    public class ParentClass
    {
        public int MyId {get; set;}
        public static string CommonField1 {get; set;}
        public static string CommonField2 {get; set;}
        public static string CommonField3 {get; set;}
        public string Changeable {get; set;}
    

    请注意,其中一些应该是protected 而不是public,您应该始终通过属性而不是直接公开公共字段。当然,如果您有多个 ParentClass 实例,它们的这些字段的值不同,那么这是不行的。

【讨论】:

  • 1.) 我该怎么做 ChildClass.commonField1 ? 2.) ParentClass 确实有不同的值。
  • @LearningJrDev 1) 将父实例公开为属性(例如c.Parent.CommonField1)或创建传递属性。请注意,传递属性通常是一种设计气味。
【解决方案2】:

如果子级和父级应该有某种关系(即共享方法/属性的公共父类),但子级需要与父级共享属性,您可以将属性请求重定向到父级(请注意,男人会获得深度嵌套子级的属性很慢):

public class Node
{
    public virtual string Field {get {return parent != null ? parent.Field : field;}}

    public Node parent;
    public List<Node> children;

    public Node()
    {
        children = new List<Node>();
    }

    public createChildren()
    {
        for(int i = 0; i < 999999; i++) 
        {
            children.Add(new ChildNode(i, this));
        }
    }
}

public class ChildNode : Node
{
    public override string Field {get {return parent.Field;}}
    public ChildNode(Node parent)
    {
        this.parent = parent;
    }
}

public class RootNode : Node
{
    public override string Field {get {return "Root";}}
    public RootNode()
    {
        this.parent = null;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-19
    • 2019-01-06
    • 1970-01-01
    相关资源
    最近更新 更多