我有以下课程
class GridBase
{
public object DataSource { get; set; }
}
class GenericGrid<T> : GridBase
{
public new T DataSource { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
GridBase 和通用网格类都可以实例化,并且也可以从任一类派生。
这是否被认为是实现这种层次结构的正确/可接受的方法?或者你应该加倍努力并像下面这样实现它
class GridBase
{
protected object dataSource;
public object DataSource { get { return dataSource; } set { dataSource = value; } }
}
class GenericGrid<T> : GridBase
{
public new T DataSource { get { return (T)dataSource; } set { dataSource = value; } }
}
Run Code Online (Sandbox Code Playgroud)
当在后代中重新引入属性时,这同样适用于非泛型类,我在这里仅使用一个泛型示例。
另一个案例和问题
abstract class SomeBase
{
protected abstract void DoSomething();
}
class Child : SomeBase
{
protected override void DoSomething()
{
/* Some implementation here */
}
}
Run Code Online (Sandbox Code Playgroud)
这里的情况是框架“X”声明 SomeBase 允许您定义自己的后代。他们创建的类(在运行时)然后从您的类(在本例中为子类)派生。但是,他们不会从 DoSomething() 的实现中调用您的 DoSomething() 方法。
就他们而言,他们也不能盲目地调用 base.Dosomething() ,因为典型的情况是他们生成的类通常是从 SomeBase 派生的,并且由于该方法是抽象的,因此无效。(就我个人而言,我不喜欢 C# 中的这种行为)。
但无论如何,不调用 base.xxx() 是好的还是可接受的设计,特别是当“意图”似乎矛盾时?
编辑从框架设计的角度来看。这样做可以/可以接受吗?如果不是,如何设计才能防止这种情况发生或更好地传达他们的意图(在这两种情况下)。
泛型继承的第二种形式(转换基类的属性)更正确,因为它不违反里氏替换原则。可以想象,泛型类的实例被转换为基类,并通过基类访问数据指向不同的属性。您需要保持两者同步,以便派生类可以替换基类。
或者,您可以实现某种策略模式,其中基类向派生类请求 Data 属性,以避免尴尬的向下转型。这就是我的想法:
public class Base {
private readonly object m_Data; //immutable data, as per JaredPar suggestion that base class shouldn't be able to change it
publlic Base(object data) {
m_Data = data;
}
protected virtual object GetData() {return m_Data;}
public Object DataSource {get {return GetData();}}
}
public class Derived<T> : Base {
private T m_Data;
public Derived():base(null){}
protected override object GetData() {return m_Data;}
protected new T Data {return m_Data;}
}
Run Code Online (Sandbox Code Playgroud)
关于第二个问题,我确信我理解这个问题。听起来您遇到的问题是框架在运行时生成代理时不调用抽象方法,这在抽象类中始终是合法的,因为执行该代码的唯一方法是通过必须重写的派生类抽象方法。
| 归档时间: |
|
| 查看次数: |
2185 次 |
| 最近记录: |