[英]How do you get the all properties of a class and its base classes (up the hierarchy) with Reflection? (C#)
所以我現在擁有的是這樣的:
PropertyInfo[] info = obj.GetType().GetProperties(BindingFlags.Public);
其中obj
是某個對象。
問題是我想要的一些屬性不在obj.GetType()
中,它們在更進一步的基類之一中。 如果我停止調試器並查看 obj,我必須挖掘一些“基礎”條目才能查看我想要獲取的屬性。 是否可以設置一些綁定標志以使其返回這些標志,或者我是否必須遞歸地挖掘Type.BaseType
層次結構並對所有這些標志執行GetProperties
?
用這個:
PropertyInfo[] info = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
編輯:當然,正確的答案是Jay的答案。 不帶參數的GetProperties()
等效於GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static )
。 BindingFlags.FlattenHierarchy
在這里不起作用。
我覺得沒那么復雜。
如果您將BindingFlags
參數刪除到 GetProperties,我認為您會得到您正在尋找的結果:
class B
{
public int MyProperty { get; set; }
}
class C : B
{
public string MyProperty2 { get; set; }
}
static void Main(string[] args)
{
PropertyInfo[] info = new C().GetType().GetProperties();
foreach (var pi in info)
{
Console.WriteLine(pi.Name);
}
}
生產
MyProperty2 MyProperty
如果您訪問Type.BaseType
,您可以獲得基本類型。 您可以遞歸地訪問每種基本類型,並且當您的類型為System.Object
時,您會知道何時觸底。
Type type = obj.GetType();
PropertyInfo[] info = type.GetProperties(BindingFlags.Public);
PropertyInfo[] baseProps = type.BaseType.GetProperties(BindingFlags.Public);
我傾向於同意 Nicolas 的觀點。 除非您知道需要反射,否則ComponentModel
是一個可行的替代方案,其優點是即使對於運行時模型(例如DataView
/ DataRowView
),您也可以獲得正確的元數據。
例如:
foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(obj))
{
Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(obj));
}
順便說一句,您還可以用它做一些簡單的 性能技巧; 你可以對反射和Delegate.CreateDelegate
做同樣的事情,但是沒有集中的地方來隱藏邏輯,這與帶有TypeDescriptor
的TypeDescriptionProvider
不同(如果這些不熟悉,請不要擔心;你可以“按原樣”使用代碼; -p)。
利用:
TypeDescriptor.GetProperties(obj);
為了完整起見,您不能以這種方式從基類中獲取 PRIVATE 字段和屬性。 您必須為此使用遞歸循環:
public static IEnumerable<PropertyInfo> GetProperties(Type type, bool forGetter)
{
// Loop over public and protected members
foreach (var item in type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{
yield return item;
}
// Get first base type
type = type.BaseType;
// Find their "private" memebers
while (type != null && type != typeof(object))
{
// Loop over non-public members
foreach (var item in type.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic))
{
// Make sure it's private!
// To prevent doubleing up on protected members
var methodInfo = forGetter ? item.GetGetMethod(true) : item.GetSetMethod(true);
if (methodInfo != null && methodInfo.IsPrivate)
{
yield return item;
}
}
// Get next base type.
type = type.BaseType;
}
}
和
public static IEnumerable<FieldInfo> GetFields(Type type)
{
// Loop over public and protected members
foreach (var item in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
{
yield return item;
}
// Get first base type
type = type.BaseType;
// Find their "private" memebers
while (type != null && type != typeof(object))
{
// Loop over non-public members
foreach (var item in type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic))
{
// Make sure it's private!
// To prevent doubleing up on protected members
if (item.IsPrivate)
{
yield return item;
}
}
// Get next base type.
type = type.BaseType;
}
}
注意:您將獲得兩次受保護的字段和屬性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.