Find a private field with Reflection?

匿名 (未验证) 提交于 2019-12-03 02:12:02

问题:

Given this class

class Foo {     // Want to find _bar with reflection     [SomeAttribute]     private string _bar;      public string BigBar     {         get { return this._bar; }     } } 

I want to find the private item _bar that I will mark with a attribute. Is that possible?

I have done this with properties where I have looked for an attribute, but never a private member field.

What are the binding flags that I need to set to get the private fields?

回答1:

Use BindingFlags.NonPublic and BindingFlags.Instance flags

FieldInfo[] fields = myType.GetFields(                          BindingFlags.NonPublic |                           BindingFlags.Instance); 


回答2:

You can do it just like with a property:

FieldInfo fi = typeof(Foo).GetField("_bar", BindingFlags.NonPublic | BindingFlags.Instance); if (fi.GetCustomAttributes(typeof(SomeAttribute)) != null)     ... 


回答3:

Get private variable's value using Reflection:

var _barVariable = typeof(Foo).GetField("_bar", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(objectForFooClass); 

Set value for private variable using Reflection:

typeof(Foo).GetField("_bar", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(objectForFoocClass, "newValue"); 

Where objectForFooClass is a non null instance for the class type Foo.



回答4:

One thing that you need to be aware of when reflecting on private members is that if your application is running in medium trust (as, for instance, when you are running on a shared hosting environment), it won't find them -- the BindingFlags.NonPublic option will simply be ignored.



回答5:

typeof(MyType).GetField("fieldName", BindingFlags.NonPublic | BindingFlags.Instance) 


回答6:

I use this method personally

if (typeof(Foo).GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Any(c => c.GetCustomAttributes(typeof(SomeAttribute), false).Any())) {      // do stuff } 


回答7:

Yes, however you will need to set your Binding flags to search for private fields (if your looking for the member outside of the class instance).

The binding flag you will need is: System.Reflection.BindingFlags.NonPublic



回答8:

Here is some extension methods for simple get and set private fields and properties (properties with setter):

usage example:

    public class Foo     {         private int Bar = 5;     }      var targetObject = new Foo();     var barValue = targetObject.GetMemberValue("Bar");//Result is 5     targetObject.SetMemberValue("Bar", 10);//Sets Bar to 10 

Code:

    ///      /// Extensions methos for using reflection to get / set member values     ///      public static class ReflectionExtensions     {         ///          /// Gets the public or private member using reflection.         ///          /// The source target.         /// Name of the field or property.         /// the value of member         public static object GetMemberValue(this object obj, string memberName)         {             var memInf = GetMemberInfo(obj, memberName);              if (memInf == null)                 throw new System.Exception("memberName");              if (memInf is System.Reflection.PropertyInfo)                 return memInf.As().GetValue(obj, null);              if (memInf is System.Reflection.FieldInfo)                 return memInf.As().GetValue(obj);              throw new System.Exception();         }          ///          /// Gets the public or private member using reflection.         ///          /// The target object.         /// Name of the field or property.         /// Old Value         public static object SetMemberValue(this object obj, string memberName, object newValue)         {             var memInf = GetMemberInfo(obj, memberName);               if (memInf == null)                 throw new System.Exception("memberName");              var oldValue = obj.GetMemberValue(memberName);              if (memInf is System.Reflection.PropertyInfo)                 memInf.As().SetValue(obj, newValue, null);             else if (memInf is System.Reflection.FieldInfo)                 memInf.As().SetValue(obj, newValue);             else                 throw new System.Exception();              return oldValue;         }          ///          /// Gets the member info         ///          /// source object         /// name of member         /// instanse of MemberInfo corresponsing to member         private static System.Reflection.MemberInfo GetMemberInfo(object obj, string memberName)         {             var prps = new System.Collections.Generic.List();              prps.Add(obj.GetType().GetProperty(memberName,                                                System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance |                                                System.Reflection.BindingFlags.FlattenHierarchy));             prps = System.Linq.Enumerable.ToList(System.Linq.Enumerable.Where( prps,i => !ReferenceEquals(i, null)));             if (prps.Count != 0)                 return prps[0];              var flds = new System.Collections.Generic.List();              flds.Add(obj.GetType().GetField(memberName,                                             System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance |                                             System.Reflection.BindingFlags.FlattenHierarchy));              //to add more types of properties              flds = System.Linq.Enumerable.ToList(System.Linq.Enumerable.Where(flds, i => !ReferenceEquals(i, null)));              if (flds.Count != 0)                 return flds[0];              return null;         }          [System.Diagnostics.DebuggerHidden]         private static T As(this object obj)         {             return (T)obj;         }     } 


回答9:

I came across this while searching for this on google so I realise I'm bumping an old post. However the GetCustomAttributes requires two params.

typeof(Foo).GetFields(BindingFlags.NonPublic | BindingFlags.Instance) .Where(x => x.GetCustomAttributes(typeof(SomeAttribute), false).Length > 0); 

The second parameter specifies whether or not you wish to search the inheritance hierarchy



回答10:

You can have a extension method to get any private field for any type:

public static T GetFieldValue(this object obj, string name) {     var field = obj.GetType().GetField(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);     return (T)field?.GetValue(obj); } 

And then access a private field of an arbitrary type:

Foo foo = new Foo(); string c = foo.GetFieldValue("_bar"); 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!