how to get both fields and properties in single call via reflection?

后端 未结 5 900
时光说笑
时光说笑 2020-12-03 05:05

I apologize if this is covered somewhere. I did research before posting!

okay, so question...I\'m using GetType( ).GetProperties, but it isn\'t returning simple inst

5条回答
  •  情深已故
    2020-12-03 05:25

    To get either properties or fields, you can say:

    var q=
        from it in type.GetMembers(bindingAttr)
        where it is PropertyInfo||it is FieldInfo
        select it;
    

    where bindingAttr could be

    var bindingAttr=
            BindingFlags.NonPublic|
            BindingFlags.Public|
            BindingFlags.Instance;
    

    Remove BindingFlags.NonPublic if you don't want to get non-public members. By the way, the query is not a single call but a single statement.


    To get the value of either a property or a field without casting it by yourself, use InvokeMember for the trick:

    static object GetValue(
            T x, object target) where T:MemberInfo {
        var invokeAttr=(
                x is FieldInfo
                    ?BindingFlags.GetField
                    :x is PropertyInfo
                        ?BindingFlags.GetProperty
                        :BindingFlags.Default)|
                BindingFlags.NonPublic|
                BindingFlags.Public|
                BindingFlags.Instance;
    
        return target.GetType().InvokeMember(
            x.Name, invokeAttr, default(Binder), target, null);
    }
    

    Similarly, to set the value:

    static void SetValue(
            T x, object target, object value) where T:MemberInfo {
        var args=new object[] { value };
        var invokeAttr=(
                x is FieldInfo
                    ?BindingFlags.SetField
                    :x is PropertyInfo
                        ?BindingFlags.SetProperty
                        :BindingFlags.Default)|
                BindingFlags.NonPublic|
                BindingFlags.Public|
                BindingFlags.Instance;
    
        target.GetType().InvokeMember(
            x.Name, invokeAttr, default(Binder), target, args);
    }
    

    It will throw if you pass a MemberInfo other than PropertyInfo or FieldInfo as the first argument, because BindingFlags.Default doesn't specify what you are going to do.

提交回复
热议问题