c# - 如何用继承的类覆盖属性?
问题描述
代码的快速示例
public class BaseSettings {}
public class SpecificSettings : BaseSettings {}
public class BaseClass
{
public virtual BaseSettings Settings {get; set;}
public void DoSomething(BaseSettings settings)
{
Settings = settings;
}
}
public class InheritedClass : BaseClass
{
public override SpecificSettings Settings {get; set;}
}
我有许多继承 BaseClass 的类,它们都将具有相同的“DoSomething”方法。但是,我希望派生类 SpecificSettings 成为调用时设置的类。
如果我使用此代码,它将生成一个错误,告诉我
'InheritedClass.Settings':类型必须是 'BaseSettings' 以匹配被覆盖的成员 'BaseSettings.Settings'
我不是 OOP 专家,但我认为继承类是BaseSettings 的一种。
我已经研究过用泛型来做这件事,但它似乎不符合我的要求,因为在某些时候我需要(在反序列化期间)让方法的返回类型为 BaseClass 类型。
解决方案
BaseClass
您的班级中有一个虚拟方法
public virtual BaseSettings Settings { get; set; }
如果您要InheritedClass
继承BaseClass
并想要override
Settings
方法,Settings
则方法签名需要与基类相同。
public class InheritedClass : BaseClass
{
public override BaseSettings Settings { get; set; }
}
但是您override
没有任何意义,因为设置与您的基类做同样的事情。
我会ISetting<T>
用合同泛型而不是继承来创建接口BaseClass
。
您可以使用BaseClass
和InheritedClass
实现ISetting<T>
并决定哪个类使用哪个设置。
如果SpecificSettings
扩展了数字属性BaseSettings
我会创建CommonProperty
类来承载属性,因为继承使类强耦合。使用组合比继承更灵活。
public class CommonProperty {
// move your BaseClass common with SpecificSettings in here.
}
public interface ISetting<T>
where T : BaseSettings
{
T Settings { get; set; }
void DoSomething(T settings);
}
public class BaseSettings { }
public class SpecificSettings : BaseSettings { }
public class BaseClass : ISetting<BaseSettings>
{
public CommonProperty commonProperty { get; set; }
public virtual BaseSettings Settings { get; set; }
public void DoSomething(BaseSettings settings)
{
Settings = settings;
}
}
public class InheritedClass : ISetting<SpecificSettings>
{
public CommonProperty commonProperty { get; set; }
public SpecificSettings Settings { get; set; }
public void DoSomething(SpecificSettings settings)
{
Settings = settings;
}
}
推荐阅读
- ruby-on-rails - Rails Postgres 配置主机被误认为数据库名称
- model - UML 模型转换
- localization - 向 Cumulocity 添加语言
- javascript - 在本机反应中正确使用动画 API
- c# - 是否可以同时连接和读取树莓派中的多个串口?
- kubernetes - cert-manager 正在使用 acme 响应程序创建新入口,而不是修改现有的
- xamarin.forms - 在android自定义渲染器代码中添加底线?
- ios - 如何在试飞中检查现有版本
- python - print(input() + input()) 如何在 python 中工作?没有变量赋值?
- azure - 带有 HTTP 触发函数应用程序的 Azure Redis 缓存?