2013-03-05 82 views
0

在泛型类中隐藏非泛型基类属性或方法的标准模式是什么?在通用类中隐藏非泛型基类属性

我有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; } } 
} 
+0

你能解释的目的,为什么你有仿制药吗?你正在使它成为T只能是一种类型的地方,你可以使用MyDataBase类型并且仍然向构造函数发送一个MyDataBaseDerived。 – 2013-03-05 01:28:10

+1

@InfinitePossiblities:'T'可以是从'MyDataBase'派生的任何类型。问题是如何将属性的返回类型更改为'T'。 – pescolino 2013-03-05 12:55:02

+0

@pescolino现在有道理,谢谢! – 2013-03-05 19:28:00

回答

1

我会去第二次(CAST)的方法,如果I W可以从这两个选择中选择:在多个地方存储相同的数据几乎是保证让它们不同步的方法。所以如果表现很重要,我会选择铸造成本(不太可能很重要) - 测量和验证。

附注:我会尽量避免new属性,因为它会导致所谓的混淆,取决于你有什么变量类型。使基类'Data受保护的财产可能成为特定样本的潜在解决方案。

1

解决方案3

反向遗传BaseFooGenericFoo<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) { 
    } 
} 
0

我认为你不能改变的类型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; 
    } 
}