C# 不从 GetType().GetFields 获取带有 BindingFlag.Default 的字段
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1155529/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Not getting fields from GetType().GetFields with BindingFlag.Default
提问by Patrick
I am using the Reflection classes in order to get all the fields inside a certain object. My problem however is that it works perfectly when the fields are inside a normal class, like:
我正在使用 Reflection 类来获取某个对象内的所有字段。然而,我的问题是,当字段位于普通类中时,它可以完美运行,例如:
class test
{
string test1 = string.Empty;
string test2 = string.Empty;
}
Here i get both test1 and test2, my problem is that i use abstraction and thus several classes combined.
在这里我得到了 test1 和 test2,我的问题是我使用了抽象,因此组合了几个类。
I got something like:
我得到了类似的东西:
class test3 : test2
{
string test4 = string.Empty;
string test5 = string.Empty;
}
class test2 : test1
{
string test2 = string.Empty;
string test3 = string.Empty;
}
class test1
{
string test0 = string.Empty;
string test1 = string.Empty;
}
But when I run it, I don't get the fields back from the GetType().GetFields(BindingFlag.Default)
.
但是当我运行它时,我没有从GetType().GetFields(BindingFlag.Default)
.
Everyone of those fields also have a property, get; set;
attached to it.
When I run the code, I get the properties all the way back to test1 but not the actual fields.
这些字段中的每一个都有一个属性,get; set;
附加到它。当我运行代码时,我将属性一直返回到 test1,但不是实际字段。
This is the code that I'm trying to get the fields with:
这是我试图获取字段的代码:
FieldInfo[] fields = Obj.GetType().GetFields(BindingFlags.Default);
foreach (FieldInfo field in fields)
I have also tried:
我也试过:
FieldInfo[] fields = Obj.GetType().GetFields(BindingFlags.Public
| BindingFlags.Instance
| BindingFlags.NonPublic
| BindingFlags.Static);
I use the same code for the properties:
我对属性使用相同的代码:
PropertyInfo[] properties = Obj.GetType().GetProperties(BindingFlags.Public
| BindingFlags.Instance
| BindingFlags.NonPublic
| BindingFlags.Static);
foreach (PropertyInfo property in properties)
Any ideas why I get the properties from the abstracted classes but not the fields?
为什么我从抽象类中获取属性而不是从字段中获取属性?
采纳答案by Sam Harwell
Edit: To get privatemembers of the base type, you have to:
编辑:要获取基本类型的私有成员,您必须:
typeof(T).BaseType.GetFields(...)
Edit again: Win.
再次编辑:赢。
Edit 3/22/13: Used Concat
instead of Union
. Since we are specifying BindingFlags.DeclaredOnly
and a type's BaseType
cannot equal itself, Union
is not needed and is more expensive.
2013 年 3 月 22 日编辑:Concat
代替Union
. 由于我们正在指定BindingFlags.DeclaredOnly
并且类型BaseType
不能等于自身,Union
因此不需要并且更昂贵。
public static IEnumerable<FieldInfo> GetAllFields(Type t)
{
if (t == null)
return Enumerable.Empty<FieldInfo>();
BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Static | BindingFlags.Instance |
BindingFlags.DeclaredOnly;
return t.GetFields(flags).Concat(GetAllFields(t.BaseType));
}
回答by David M
Properties are inherited, fields are not. Protected fields are visible to descendant classes, but not inherited by them. In other words, the descendant class actually has the properties of its base class, but it is just able to see the fields.
属性是继承的,字段不是。受保护的字段对后代类可见,但不被它们继承。换句话说,后代类实际上具有其基类的属性,但它只能看到字段。
回答by Fredrik M?rk
A type that inherits another type cannot see private parts of that other type, it can see protected, internal and public parts. Consider the following code:
继承另一个类型的类型不能看到其他类型的私有部分,它可以看到受保护的、内部的和公共的部分。考虑以下代码:
class A
{
// note that this field is private
string PrivateString = string.Empty;
// protected field
protected string ProtectedString = string.Empty;
}
class B : A { }
class Program
{
static void Main(string[] args)
{
Console.WriteLine("B Fields:");
B b = new B();
b.GetType()
.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
.ToList()
.ForEach(f => Console.WriteLine(f.Name));
Console.WriteLine("A Fields:");
A a = new A();
a.GetType()
.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
.ToList()
.ForEach(f => Console.WriteLine(f.Name));
}
}
The output of this program is the following:
该程序的输出如下:
B Fields:
ProtectedString
A Fields:
PrivateString
ProtectedString
So, the type A
has two fields; PrivateString
and ProtectedString
. Type B
has one; ProtectedString
, that it inherits from A
. If you wish to "reach" PrivateString
through the type B
, you will need to navigate to its base type (b.GetType().BaseType
).
因此,该类型A
有两个字段;PrivateString
和ProtectedString
。类型B
有一个;ProtectedString
,它继承自A
. 如果您希望PrivateString
通过 type来“到达” B
,则需要导航到其基本类型 ( b.GetType().BaseType
)。
Note though, that even if the type B
reports to have a field called ProtectedString
, this field is still not declared in B
; it is declared in A
. This can be examined by adding BindingFlags.DeclaredOnly
to the GetFields
calls in the above sample program; GetFields
will return no fields for B
, and two for A
.
但请注意,即使该类型B
报告有一个名为 的字段ProtectedString
,该字段仍未在B
; 中声明。它在A
. 这可以通过添加BindingFlags.DeclaredOnly
到GetFields
上述示例程序中的调用来检查;GetFields
不会为 返回任何字段,为 返回B
两个字段A
。
Translated to your code sample, this means that the type test3
does not contain the fields test2
and test3
, since they are private to the type test2
(the similarity of the field names and type names make that sentence somewhat confusing, I am afraid).a
转换为您的代码示例,这意味着该类型test3
不包含字段test2
and test3
,因为它们是该类型的私有test2
字段(字段名称和类型名称的相似性使该句子有些混乱,恐怕)。
回答by Jacob
You can use this extension method to recursively traverse a type's inheritance hierarchy all the way up to object, effectively returning all fields of the type and all its ancestors:
您可以使用此扩展方法递归遍历类型的继承层次结构,直到对象,有效地返回该类型的所有字段及其所有祖先:
public static class ReflectionExtensions
{
public static IList<FieldInfo> GetAllFields(this Type type, BindingFlags flags)
{
if(type == typeof(Object)) return new List<FieldInfo>();
var list = type.BaseType.GetAllFields(flags);
// in order to avoid duplicates, force BindingFlags.DeclaredOnly
list.AddRange(type.GetFields(flags | BindingFlags.DeclaredOnly));
return list;
}
}
(Untested, YMMV)
(未经测试,YMMV)
回答by Carlo V. Dango
If you just want the names for both properties and fields, use
如果您只想要属性和字段的名称,请使用
private static IEnumerable<string > GetAllFieldsAndProperties(Type t)
{
if (t == null)
return Enumerable.Empty<string>();
BindingFlags flags = BindingFlags.Public
| BindingFlags.NonPublic
| BindingFlags.Static
| BindingFlags.Instance
| BindingFlags.DeclaredOnly;
return t.GetFields(flags).Select(x=>x.Name)
.Union(GetAllFieldsAndProperties(t.BaseType))
.Union(t.GetProperties(flags).Select(x=>x.Name));
}
回答by Makeman
Enumeration of all type fields including private members from base classes.
枚举所有类型字段,包括来自基类的私有成员。
public static IEnumerable<FieldInfo> EnumerateFields(this Type type, BindingFlags flags) =>
type.BaseType?.EnumerateFields(flags)
.Concat(type.GetFields(flags | BindingFlags.DeclaredOnly)) ??
type.EnumerateFields(flags);