Find a private field with Reflection?

前端 未结 10 1385
自闭症患者
自闭症患者 2020-11-22 16:17

Given this class

class Foo
{
    // Want to find _bar with reflection
    [SomeAttribute]
    private string _bar;

    public string BigBar
    {
        ge         


        
10条回答
  •  孤城傲影
    2020-11-22 16:52

    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;
            }
        }
    

提交回复
热议问题