代码之家  ›  专栏  ›  技术社区  ›  moggizx

用子类重写属性

  •  0
  • moggizx  · 技术社区  · 12 年前

    假设我在抽象类AbstractClass中有这样的属性:

    protected MyClass MyProperty { get; set; }
    

    这个属性用于AbstractClass中的许多(虚拟)方法。在AbstractClass的一个子类中,我希望MyProperty是MyClass的一个子类,这可能吗?或者我必须强制转换它?

    MyProperty = new SubclassOfMyClass();
    ((SubclassOfMyClass)MyProperty).Method();
    

    看起来不太好。。。我尝试使用“new”关键字来隐藏MyProperty,如下所示:

    protected new SubclassOfMyClass MyProperty { get; set; }
    

    但这并没有像我想象的那样成功,因为它似乎创建了第二个MyProperty,并导致AbstractClass中的那个始终为null。

    所以我想出了一个看起来有点像黑客的办法:

    protected new SubclassOfMyClass MyProperty 
    {
        get { return base.MyProperty as SubclassOfMyClass; }
        set { base.MyProperty = value; }
    }
    

    有更好的方法吗?

    1 回复  |  直到 12 年前
        1
  •  0
  •   Ahmed KRAIEM    12 年前

    您可以使用泛型:

    public abstract class AbstractClass<T> where T : MyClass, new() {
        protected T MyProperty { get; set; }
    }
    
    public class SubClass : AbstractClass<SubclassOfMyClass> {
    }
    

    编辑:

    这是对你的“黑客攻击”的回应:

    请考虑以下代码:

    public class MyClass { }
    public class SubclassOfMyClass : MyClass { }
    
    public abstract class AbstractClass
    {
        public MyClass MyProperty { get; set; }
    }
    
    public class Subclass : AbstractClass
    {
        public new SubclassOfMyClass MyProperty
        {
            get { return base.MyProperty as SubclassOfMyClass; }
            set { base.MyProperty = value; }
        }
    }
    
    public class Test
    {
        public static void Main()
        {
            AbstractClass sub = new Subclass();
            sub.MyProperty = new MyClass();
    
            Subclass sub2 = (Subclass)sub;//casting succeeds since sub is Subclass 
            if (sub2.MyProperty == null)
                Console.WriteLine("sub2.MyProperty is null!");
        }
    }
    

    这实际上会打印“sub2.MyProperty为null!”。铸造后 sub sub2 然后访问 sub2.MyProperty base.MyProperty 类型为 MyClass base.MyProperty as SubclassOfMyClass 按预期返回null。所以如果你打算使用 new 关键字你应该真正知道幕后发生了什么。