2013-03-05 80 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; 
    } 
}