[英]Can't get GetSetMethod for property with private setter from base class
[英]Reflection can't find private setter on property of abstract class
當我在抽象類中擁有此屬性時:
public IList<Component> Components { get; private set; }
然后當我打電話:
p.GetSetMethod(true)
如果p是指向我的屬性的PropertyInfo對象,則為null。
但是,如果我將屬性setter更改為protected,我可以通過反射看到它。 為什么是這樣? 我似乎沒有回憶起非抽象類的這個問題......
我假設您在抽象類的派生類型的對象上調用它。 該課程根本沒有屬性設定者。 它只位於您的抽象基礎上。 這就是為什么它在您將其標記為protected
。 獲取屬性設置器時,需要使用抽象類' Type
。
這是一個老線程,但我最近遇到了類似的問題,上面沒有一個對我有用。 添加我的解決方案,因為它可能對其他人有用。
如前所述,如果屬性的setter是private,則它不存在於繼承的類中。 對我來說DeclaringType
的是使用PropertyInfo
DeclaringType
降低一級
因此,使用setter檢索屬性的代碼如下所示:
var propertyInfo = typeof(MyClass)
.GetProperty("Components", BindingFlags.NonPublic | BindingFlags.Instance)
.DeclaringType
.GetProperty("Components", BindingFlags.NonPublic | BindingFlags.Instance);
在這種情況下, propertyInfo
包含SetMethod
的值,因此您可以使用反射設置值。
C#Interactive窗口中的一些簡短實驗表明,對於在A
類上聲明的屬性P
,以下工作正常:
var p = typeof(A).GetProperty("P").GetSetMethod(true)
但是只要你用A
的子類嘗試相同的東西, GetSetMethod
就不再解析私有set
訪問器:
// class B : A {}
var p = typeof(B).GetProperty("P").GetSetMethod(true) // produces 'null'.
換句話說,當反射類型與屬性的聲明類型相同時,您嘗試的只顯示僅適用於private
訪問器。
訣竅是使用BindingFlags枚舉來指定在獲取PropertyInfo
對象時希望包含私有成員:
PropertyInfo p = obj.GetType().GetProperty("Components", BindingFlags.NonPublic | BindingFlags.Instance);
建立@piotrwolkowski的工作
var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
var propertyInfo = typeof(MyClass).GetProperty("Components", flags);
// only go to the declaring type if you need to
if (!propertyInfo.CanWrite)
propertyInfo = propertyInfo.DeclaringType.GetProperty("Components", flags);
我將公共和非公共添加到我的用例的綁定標志(它可能是矯枉過正的,我沒有時間進一步追求它)
我正在設置一個對象的實例,該對象繼承自具有公共get和private set的抽象基礎
再次,所有信用@piotrwolkowski
以下實驗為我揭開了這個問題。 請注意,基類不必是abstract
來重現問題。
public class Base
{
public string Something { get; private set; }
}
public class Derived : Base { }
public class MiscTest
{
static void Main( string[] args )
{
var property1 = typeof( Derived ).GetProperty( "Something" );
var setter1 = property1.SetMethod; //null
var property2 = typeof( Base ).GetProperty( "Something" );
var setter2 = property2.SetMethod; //non-null
bool test1 = property1 == property2; //false
bool test2 = property1.DeclaringType == property2.DeclaringType; //true
var solution = property1.DeclaringType.GetProperty( property1.Name );
var setter3 = solution.SetMethod; //non-null
bool test3 = solution == property1; //false
bool test4 = solution == property2; //true
bool test5 = setter3 == setter2; //true
}
}
我從中學到和發現令人驚訝的是,在PropertyInfo
上派生類型是不同的實例比PropertyInfo
上的基本類型。 奇怪的!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.