我有一个抽象类,GenericModel
,它定义了一个模板方法如下:
public virtual string DoStuff<TType>(IEnumerable<TType> input)
where TType : GenericModel { return null; }
然后我有一个继承自 GenericModel
的类称为 BasicModel
代表 GenericModel
的某个子集有足够的共同点来保证另一种结构。虽然这是一个具体的类,但它从未实际实例化,而是其他类继承自它,因为有许多共同的属性不一定在每个 GenericModel
中都有。但那是在每个 BasicModel
(出于示例目的,我们会说每个 BasicModel
都有一个 id
属性)。
如果我有一个继承自 BasicModel
的类称为 ChildModel
,我想覆盖 DoStuff()
,这是允许的,因为 ChildModel
继承自 BasicModel
继承自 GenericModel
.所以我定义了一个覆盖方法(在 ChildModel
中)如下:
public override string DoStuff<ChildModel>(IEnumerable<ChildModel> input){
foreach(var data in input){
var foo = data.id;
//Do stuff with foo
}
//Do more stuff
}
问题是 Visual Studio 突出显示了 data.id
作为一个错误,说 data
没有名为 id
的属性.我的假设是这是由于 where TType : GenericModel
模板方法的一部分;它忽略中间 BasicModel
所以我无法访问 BasicModel
中定义的属性.
这对我来说似乎很奇怪,因为我声明输入必须由ChildModel
组成s 这将全部定义为 BasicModel
的子类, 有一个 id
属性(property)。
有没有办法访问 ChildModel
中的这些中间类属性?的覆盖 DoStuff()
还是我设置继承的方式不可能?是否有任何解决方法或更改可以允许使用这些属性?
编辑:从评论和回答看来,我对模板方法存在根本性的误解。我真正想做的是在 GenericModel
中定义一个通用方法。将 IEnumerable<GenericModel>
作为输入然后在每个子类中被覆盖,其中覆盖使用 IEnumerable<ChildClass>
反而。显然,我定义的结构可能无法实现该目标。
最佳答案
public override string DoStuff<ChildModel>(IEnumerable<ChildModel> input) { ... }
没有将 DoStuff
专门化为仅与 ChildModel
一起使用,而只是将 TType
参数重命名为 ChildModel
.这相当于
public override string DoStuff<T>(IEnumerable<T> input) { }
这不会编译,因为您还需要保留基类对 TType
的约束。
DoStuff
方法的通用约束意味着覆盖必须统一处理所有子类型。听起来您希望每个子类都支持 GenericModel
的一个特定子类型。在这种情况下,您可以将通用参数移动到基类并在每个子类中指定它,例如
public abstract class BaseClass<TType> where TType : GenericModel {
public virtual string DoStuff(IEnumerable<TType> input) { ... }
}
public class SubClass : BaseClass<ChildModel> {
public override string DoStuff(IEnumerable<ChildModel> input) { ... }
}
关于c# - 在重写模板方法中访问中间类属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38485225/