[英]hiding non-generic base class property in a generic class
在泛型类中隐藏非泛型基类属性或方法的标准模式是什么?
我有2个解决方案实际上是做同样但不同的方法。 解决方案之一使用更多内存,因为基类和派生类引用相同的对象,而解决方案2因为转换而慢。(或者我错了?)
基类:
public class MyDataBase {}
public class MyDataDerived : MyDataBase {}
public class BaseFoo
{
private readonly MyDataBase _data;
public MyDataBase Data { get { return _data; } }
public BaseFoo(MyDataBase data) {
_data = data;
}
}
解决方案1:
public class GenericFooWithHiding<T> : BaseFoo where T : MyDataBase
{
private readonly T _data;
public GenericFooWithHiding(T data) : base(data) { _data = data; }
public new T Data { get { return _data; } }
}
解决方案2:
public class GenericFooWithCasting<T> : BaseFoo where T : MyDataBase
{
public GenericFooWithCasting(T data) : base(data) {}
public new T Data { get { return base.Data as T; } }
}
如果我从这两个中选择的话,我会选择第二种(强制转换)方法:将相同的数据存储在多个地方是非常有保证的方法让它们不同步。 因此,如果表现很重要,我会发挥铸造成本(不太可能是重要的) - 测量和验证。
旁注:我会尝试避免使用new
属性,因为根据您拥有的变量类型,它会引起混淆。 使基类' Data
属性受到保护可能是特定样本的潜在解决方案。
解决方案3
反转BaseFoo
和BaseFoo
GenericFoo<T>
之间的继承关系,因此泛型的使用变得很重要,根本不需要隐藏。
public class MyDataBase {
}
public class MyDataDerived: MyDataBase {
}
public class GenericFoo<T> where T: MyDataBase {
public GenericFoo(T data=default(T)) {
}
public T Data {
get {
return _data;
}
}
protected readonly T _data;
}
public class DerivedFoo: GenericFoo<MyDataDerived> {
public DerivedFoo(MyDataDerived data=default(MyDataDerived))
: base(data) {
}
}
public class BaseFoo: GenericFoo<MyDataBase> {
public BaseFoo(MyDataBase data=default(MyDataBase))
: base(data) {
}
}
我假设您无法更改BaseFoo
类型,因为否则您可以首先将其设置为通用。
我不会使用new
来更改返回类型,因为这可能会让人感到困惑。 例如:此代码段中的data
类型是什么?
GenericFoo<MyDataDerived> foo = new GenericFoo<MyDataDerived>(new MyDataDerived());
var data = ((BaseFoo)foo).Data;
它是MyDataBase
(调用BaseFoo
)。 然而,如果你在一个虚拟财产BaseFoo
这是在覆盖GenericFoo
,将被称为?:
public class BaseFoo
{
public virtual MyDataBase MoreData
{
get
{
return _data;
}
}
}
public class GenericFoo<T> : BaseFoo where T : MyDataBase
{
public override MyDataBase MoreData
{
get
{
return _someOtherData;
}
}
}
// which property is called?
var data = ((BaseFoo)foo).MoreData;
这次调用是GenericFoo
。 由于这通常是预期的行为,我建议不要使用new
。
我会在GenericFoo
实现一个方法来避免使用new
(我会使用一个强制转换):
public class GenericFoo<T> : BaseFoo
where T : MyDataBase
{
public T GetData()
{
return (T)base.Data;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.