2009-12-17 49 views
1

我有從外部庫中一個基類,我不能修改 - 這裏的相關部分:設置在繼承類的構造函數的私有財產價值

public class BaseClass 
{ 
    List<string> _values; 
    public Values { get { return _values; } } 
} 

我繼承BaseClass的,和我要_values設置爲從列表(T)在構造函數中繼承的類:

public InheritingClass : BaseClass 
{ 
    public InheritingClass():base() 
    { 
      //set base._values = new InhertingList<string>(); ? 
    } 
} 

什麼是設置base._values有最好的方法是什麼?有沒有辦法找到什麼私人變量是由值提取和設置,以防私人變量將來重新命名?

還有其他的方法,我可以完成我需要做的,但如果我能做到以下幾點,這將是迄今爲止比實現我的目標,而不設置專用屬性值的任何方式更快。

+1

如何外部庫初始化_values?它是在內部處理的,還是存在某種可以調用/覆蓋的「InitializeList()」方法? – Ray 2009-12-17 20:57:29

+0

我想象它發生在構造函數中 - 無論如何,沒有方法可以覆蓋並設置它。我仍然被卡在設置方法中的_values。 – jball 2009-12-17 21:06:27

回答

6

保持它私有的,顧名思義,是爲了防止這個確切的情況。

的最好的辦法是實行保護的二傳手:

public class BaseClass 
{ 
    public Values { 
     get { return _values; } 
     protected set { _values = value; } 
    } 
} 

這樣,你的InheritingClass訪問的制定者,並且可以做:

this.Values = new InhertingList<string>(); 

但因爲你不能改變基類,從技術上來說,可以通過反射來實現這一點(在完全信任的情況下)。我不推薦這種方法,雖然:

FieldInfo field = typeof(BaseClass).GetField("_value", BindingFlags.Instance | BindingFlags.NonPublic); 
field.SetValue(this, this.Values = new InhertingList<string>()); 

做你正在嘗試什麼樣的危險,順便說一句,就是你要通過改變基類的東西,你提供定義的實現。引入細微的錯誤非常容易,因爲你(有目的地)「打破」了基類中的實現細節。

我會嘗試重新考慮你的算法,並看看是否有解決此問題的另一種方式。

+1

他不能修改基類 – 2009-12-17 20:58:45

+0

我知道 - 我添加了反射示例,顯示它是如何在技術上做到這一點的...... – 2009-12-17 21:04:12

+1

這個工程,但只有當你知道私人領域的名稱 - 米不確定他做了什麼。 – ShdNx 2009-12-17 21:07:00

0

不,沒有辦法做你想找的東西。私有變量是私有的,即它們不能被任何代碼看到或改變。

2

如果您確實需要設置該值,則可以使用反射。但這不是很好的編碼風格,可能會很慢。

編輯: 可能可以拆卸您的BaseClass的,並改變其實現。那麼你可能不得不拆開整個圖書館。

也許你可以提供您的問題的更多細節?

0

通常情況下,當字段沒有突變的方法,你會使用構造函數的類的實例化對象(和它的相關領域)。

BaseClass base = new BaseClass(List<string> yourList); 
+0

BaseClass只有一個零參數構造函數。 – jball 2009-12-17 21:07:53

1

通常,當你沒有與提供現場可訪問的setter屬性,這意味着你不應該修改從任何地方的那場,但BaseClass的 - 如果BaseClass的類的創作者將有希望你能夠修改這個領域,他已經暴露了一個受保護的setter或類似的東西的財產。所以一般不建議破解它。

你當然可以通過反思來做到這一點,只要你知道私人領域的名稱 - 我不認爲有可能提取財產的主體。

至於其他答案:他寫道:「我有一個外部庫的基類,我無法修改」。

1

您不能設置私有財產。您將不得不從另一個基類繼承,或者創建自己的基類來提供行爲。

當然,根據應用程序運行的信任級別,您可以通過反射設置私有變量,但這實際上是解決設計中實際問題的方法。

0

你總是可以利用「新」的關鍵字,但如果該類投回其基本對象

public InheritingClass : BaseClass 
{ 
    public InheritingClass() 
    { 
      Values = new InhertingList<string>(); ? 
    } 

    public new List<string> Values { get; private set; } 
} 

要訪問您可以使用反射私有字段繼承的方法將被忽略,但是由於字段是私人的我不確定繼承類將如何從更改私有字段類型中受益。

public InheritingClass : BaseClass 
{ 
    private static FieldInfo _valueField = typeof(BaseClass).GetField("_values", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); 

    public InheritingClass() 
    { 
     _valueField.SetValue(this, new InhertingList<string>()); 
    } 
} 

http://msdn.microsoft.com/en-us/library/6z33zd7h(v=vs.110).aspx