繁体   English   中英

将非泛型基类属性隐藏在泛型类中

[英]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

反转BaseFooBaseFoo 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM