重载属性

本文关键字:属性 重载 | 更新日期: 2023-09-27 18:20:16

我有一个类a,它包含一个类B的对象作为属性。我想派生类B,还想确保类A中的属性指向派生的类对象。因此,我想我需要派生类A,同时重载该属性。结构如下:

public class A {
  public List<B> X{get; set;}
}
public class B {
}
public class C : B {
  string extraProperty {get; set;}
}
public class D : A {
     // I want property X to be of type C.
}

我尝试将类A中的属性X声明为虚拟,然后在类D中使用重写X,但这会导致错误D:X must be of type B to match overriden member A:X。我读到C#不支持属性重载。有什么建议吗?我该怎么做?

编辑:我不能更改A类和B类,因为它们正在其他地方使用。

重载属性

正如评论中所说,实现这一点的方法是通过泛型。

public class A<T> where T : B {
    public List<T> X { get; set; }
}
public class B {
}
public class C : B {
    string ExtraProperty { get; set; }
}
public class D : A<C> {
   // Property X is of type C.
}
public class E : A<B> {
   // Property X is of type B.
}

首先,很少有人将List<T>作为读写属性公开。IList<T>偶尔会被属性公开,但List<T>唯一应该被属性公开的时间是该属性应该标识列表,而不是封装其内容。

我怀疑您真正想要做的是持有一个私有列表或数组,并拥有一个返回包装器对象的属性,该对象将允许通过IList<T>接口访问它。如果只允许只读访问,并且基类包含BaseFoo的列表并具有类型为IList<BaseFoo>的属性,则派生类可以包含DerivedFoo的集合并使其属性返回IList<DefivedFoo>。将派生类引用强制转换为基类类型,然后请求该属性的代码将获得IList<BaseFoo>

请注意,如果您想对集合进行读写访问,那么这种方法就不会真正起作用。如果代码将派生类对象强制转换为基类对象,那么它可能会得到IList<BaseFoo>。如果允许写入,则集合将不再仅由DerivedFoo组成。