0

我有一个 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 类,因为它们正在其他地方使用。

4

2 回答 2

2

正如评论中所述,这样做的方法是通过泛型。

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.
}
于 2013-06-27T23:06:45.713 回答
1

首先,将 a 公开为读写属性的情况极为罕见。偶尔,但唯一应该由属性公开的时间是该属性应该标识一个列表,而不是封装其内容List<T>IList<T>List<T>

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

请注意,如果您希望对集合具有读写访问权限,则该方法实际上行不通。如果代码将派生类对象转换为基类对象,那么它可以得到一个IList<BaseFoo>. 如果允许对其进行写入,则该集合将不再仅包含DerivedFoo.

于 2013-06-27T23:19:56.053 回答