2011-09-14 47 views
2

我見過this,但我想知道是否有可能強制重寫未標記爲虛擬的成員或派生類型的抽象(因此不應該破壞基礎對象功能)。是否可以使用派生類型強制覆蓋未標記爲虛擬或抽象的成員?

我特別指的是覆蓋:

IDictionary<TKey, TValue> Dictionary { get; } 

KeyedCollection<TKey, TValue> 

與實現IDictionary的另一成員類型,使用另一種內部存儲集合。

有沒有可能繞過限制?

請注意,我不想爲此使用擴展名(在我的情況下,它無論如何不會有幫助)。

+1

你」我承認你不能重寫非虛擬的東西,你只能隱藏,所以你問你是否可以*強迫重寫非虛擬的東西?*如果你不能做A,你肯定不能*強制* A. –

+1

如果你讀過其他問題,你的方式有什麼不同,所以你不知道答案? – Jon

+0

如果你是**強制**覆蓋,避免使用'virtual' /'abstract'的意義何在? –

回答

5

無.net中的方法必須標記爲顯式虛擬或抽象來覆蓋它。

編輯:鑑於編輯的問題,這聽起來像你需要創建一個實現IDictionary<TKey, TValue>(我認爲KeyedCollection所做的)的自定義類,然後添加另一個索引器,允許您通過TKey獲取對象。索引是這樣的:

TValue this[TKey key] { get { ... } } 

如果你願意,你可以通過委託給私人KeyedCollection<TKey, TValue>外地趕回幾乎所有的IDictionary的方法和屬性,併爲那些要實現不同的你就可以自由這樣做。全班的答案太長,否則我會發布。

這又朝好的方向發展的實踐Prefer Composition over Inheritance

+0

+1 .net – amod

+0

所以你的意思是我應該完全重寫KeyedCollection;有沒有一種方法可以訪問原始實現而不是反編譯(在定義中,我可以看到成員,而不是它們的內容)? –

+1

如果你正在改寫KeyedCollection,你可能會做錯了。 KeyedCollection繼承Collection ,所以你可以做同樣的事情。如果你明確需要一個KeyedCollection(因爲你將它傳遞給了一個需要的方法,並且你不能改變這個方法),那麼你就被卡住了 - 你做的任何事情都不會讓其他方法調用你的Dictionary屬性。另一方面,如果你只是在你的代碼中使用它,你應該實現KeyedCollection所做的所有相同的方法,並且在你的類的私有KeyedCollection中實現你不想改變的KeyedCollection。 –

3

如果.NET就像C++一樣,這在物理上是不可能的,因爲虛擬實現爲指向函數的指針,非虛擬實現爲固定函數地址。

所以,沒有。

即使您插入反射或指針或任何其他東西,您沒有放置新函數指針的地方,因爲虛擬/抽象保留它。

也許你會看到反彙編的代碼是最好的 - 看看如何調用虛函數,並比較非虛函數的調用方式。

0

至於其他的答案說,你不能覆蓋在派生類中,但你可以隱藏基實現:

static void Main(string[] args) 
{ 
    Console.WriteLine("Animal: {0}", new Animal().NumberOfLegs); 
    Console.WriteLine("Caterpillar: {0}", new Caterpillar().NumberOfLegs); 

    Console.ReadKey(); 
} 

public class Animal 
{ 
    public int NumberOfLegs { get { return 1; } } 
} 

public class Caterpillar : Animal 
{ 
    public new int NumberOfLegs { get { return 100; } } 
} 
+1

謝謝,是的,我知道,但不幸的是,如果將集合作爲基類,基礎成員將被使用。 –

相關問題