无需覆盖基本属性即可添加其他属性

时间:2012-02-27 17:08:48

标签: c#

我有一些派生自抽象基类的类。具体类通过对基类的引用存储在容器中。具体类有许多属性,用于绑定到FixedDocument中的页面。

我想在运行时向具体类添加aditional属性,这些属性也将绑定到FixedDocument页面。我查看了装饰器模式,但似乎我必须覆盖装饰器类中的所有具体类属性才能使它们可见。有没有办法添加一个从继承基本属性值的具体类派生的包装器,如下所示:

    class BaseClass
    {
        public string Name { get; set; }
    }

    class ConcreteClass : BaseClass
    {
        public int MyProperty { get; set; }
    }

    class ConcreteClassWrapper : ConcreteClass
    {
        public int AdditionalProperty { get; set; }

        public ConcreteClassWrapper(ConcreteClass cc) 
        {
            base = cc;
        }
    }

    private static void RunTime()
    {
        List<BaseClass> list = new List<BaseClass>();

        ConcreteClass cc = new ConcreteClass()
        {
            Name = "Original",
            MyProperty = 5
        };

        list.Add(cc);

        cc = new ConcreteClassWrapper(cc)
        {
            AdditionalProperty = 10
        };
    }

显然我不能设置'base = cc'。反正有没有实现这个目标?

2 个答案:

答案 0 :(得分:0)

你可以修改ConcreteClass以便它有一个额外的构造函数:

class ConcreteClass : BaseClass
{
    public int MyProperty { get; set; }

    public ConcreteClass(ConcreteClass copy)
    {
        this.MyProperty = copy.MyProperty;
    }
}

class ConcreteClassWrapper : ConcreteClass
{
    public int AdditionalProperty { get; set; }

    public ConcreteClassWrapper(ConcreteClass cc)
        base(cc)
    {

    }
}

答案 1 :(得分:0)

您可以想象要像这样定义包装类

class ConcreteClassWrapper : ConcreteClass
{
    public string Name { get; set; } // Inherited from BaseClass
    public int MyProperty { get; set; } // Inherited from ConcreteClass
    public int AdditionalProperty { get; set; } 
}

它包含在所有基类中声明的所有成员,因为它继承了它们。

您可以创建这样的新实例(假设您有默认构造函数)

var wrapper = new ConcreteClassWrapper { 
    Name = "xy", 
    MyProperty = 5, 
    AdditionalProperty = 7
};

但是,如果您希望包装器成为真正的包装器,请不要从基类继承

class ConcreteClassWrapper
{
    private ConcreteClass _cc;

    public ConcreteClassWrapper(ConcreteClass cc)
    {
        _cc = cc;
    }

    public string Name { get { return _cc.Name; } set { _cc.Name = value; } }
    public string MyProperty{ get { return _cc.MyProperty; } set { _cc.MyProperty = value; } }
    public int AdditionalProperty { get; set; } 
}