Why is my Type.GetFields (BindingFlags.Instance | BindingFlags.Public) not working?

My code can see non-public members, but not public ones. Why?

FieldInfo[] publicFieldInfos = t.GetFields(BindingFlags.Instance | BindingFlags.Public); 

returns nothing.

Note. I am trying to get properties in an abstract class as well as a specific class. (And also read the attributes).

The MSDN example works with two flags (BindingFlags.Instance | BindingFlags.Public) , but my mini-inheritance example is below.

 private void RunTest1() { try { textBox1.Text = string.Empty; Type t = typeof(MyInheritedClass); //Look at the BindingFlags *** NonPublic *** int fieldCount = 0; while (null != t) { fieldCount += t.GetFields(BindingFlags.Instance | BindingFlags.NonPublic).Length; FieldInfo[] nonPublicFieldInfos = t.GetFields(BindingFlags.Instance | BindingFlags.NonPublic); foreach (FieldInfo field in nonPublicFieldInfos) { if (null != field) { Console.WriteLine(field.Name); } } t = t.BaseType; } Console.WriteLine("\n\r------------------\n\r"); //Look at the BindingFlags *** Public *** t = typeof(MyInheritedClass); FieldInfo[] publicFieldInfos = t.GetFields(BindingFlags.Instance | BindingFlags.Public); foreach (FieldInfo field in publicFieldInfos) { if (null != field) { Console.WriteLine(field.Name); object[] attributes = field.GetCustomAttributes(t, true); if (attributes != null && attributes.Length > 0) { foreach (Attribute att in attributes) { Console.WriteLine(att.GetType().Name); } } } } } catch (Exception ex) { ReportException(ex); } } private void ReportException(Exception ex) { Exception innerException = ex; while (innerException != null) { Console.WriteLine(innerException.Message + System.Environment.NewLine + innerException.StackTrace + System.Environment.NewLine + System.Environment.NewLine); innerException = innerException.InnerException; } } public abstract class MySuperType { public MySuperType(string st) { this.STString = st; } public string STString { get; set; } public abstract string MyAbstractString { get; set; } } public class MyInheritedClass : MySuperType { public MyInheritedClass(string ic) : base(ic) { this.ICString = ic; } [Description("This is an important property"), Category("HowImportant")] public string ICString { get; set; } private string _oldSchoolPropertyString = string.Empty; public string OldSchoolPropertyString { get { return _oldSchoolPropertyString; } set { _oldSchoolPropertyString = value; } } [Description("This is a not so importarnt property"), Category("HowImportant")] public override string MyAbstractString { get; set; } } 

EDIT

Here is my code after I accepted the advice below:

 private void RunTest1() { try { textBox1.Text = string.Empty; Type t = typeof(MyInheritedClass); //Look at the BindingFlags *** NonPublic *** int fieldCount = 0; while (null != t) { fieldCount += t.GetFields(BindingFlags.Instance | BindingFlags.NonPublic).Length; PropertyInfo[] nonPublicFieldInfos = t.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic); foreach (PropertyInfo field in nonPublicFieldInfos) { if (null != field) { Console.WriteLine(field.Name); } } t = t.BaseType; } Console.WriteLine("\n\r------------------\n\r"); //Look at the BindingFlags *** Public *** t = typeof(MyInheritedClass); PropertyInfo[] publicFieldInfos = t.GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (PropertyInfo field in publicFieldInfos) { if (null != field) { Console.WriteLine(field.Name); textBox1.Text += field.Name + System.Environment.NewLine; DescriptionAttribute[] attributes = (DescriptionAttribute[])field.GetCustomAttributes(typeof(DescriptionAttribute), false); if (attributes != null && attributes.Length > 0) { foreach (Attribute att in attributes) { Console.WriteLine(att.GetType().Name); } } } } } catch (Exception ex) { ReportException(ex); } } private void ReportException(Exception ex) { Exception innerException = ex; while (innerException != null) { Console.WriteLine(innerException.Message + System.Environment.NewLine + innerException.StackTrace + System.Environment.NewLine + System.Environment.NewLine); } } public abstract class MySuperType { public MySuperType(string st) { this.STString = st; } public string STString { get; set; } public abstract string MyAbstractString {get;set;} } public class MyInheritedClass : MySuperType { public MyInheritedClass(string ic) : base(ic) { this.ICString = ic; } [Description("This is an important property"),Category("HowImportant")] public string ICString { get; set; } private string _oldSchoolPropertyString = string.Empty; public string OldSchoolPropertyString { get { return _oldSchoolPropertyString; } set { _oldSchoolPropertyString = value; } } [Description("This is a not so importarnt property"), Category("HowImportant")] public override string MyAbstractString { get; set; } } 
+4
source share
2 answers

As a rule, you will not find any open fields . Assuming your typical class is structured something like this:

 public class MyClass { private int myField; public int MyProperty { get { return myField; } } } 

Please note that the field ( myField ) is private, while the property ( MyProperty ) is publicly available.

So, to find the fields, you will probably get the maximum mileage:

 // note: fields -> generally non-public Type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic) 

While the opposite is true for properties: you are likely to get maximum mileage:

 // note: properties -> generally public Type.GetProperties(BindingFlags.Instance | BindingFlags.Public) 

Obviously, if you want to find all (public and non-public) members of a certain type (field / property), you will have to use:

 Type.GetFields( // (or GetProperties) BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ) 
+7
source

Perhaps because you are using GetFields and the class does not have any open fields: properties and fields are two different things.

Try using GetProperties instead of GetFields .

+11
source

Source: https://habr.com/ru/post/1312566/


All Articles