C# 使用反射检测属性上的访问修饰符类型

C# 使用反射检测属性上的访问修饰符类型,c#,reflection,properties,access-modifiers,C#,Reflection,Properties,Access Modifiers,我已经编写了一些代码来使用反射查看属性。我使用反射从类中检索了属性列表 但是,我需要知道该财产是公共的还是受保护的。例如: public string Name{get;set;} protected int Age{get;set;} PropertyInfo类似乎没有公开有关该属性的信息。还有其他方法吗?因为属性只是一对get/set方法的语法糖分,所以不存在属性反射的“可访问性”。相反,您必须分别找出get和set方法的可访问性级别。为此,使用和方法检索适当的MethodInfo对象,

我已经编写了一些代码来使用反射查看属性。我使用反射从类中检索了属性列表

但是,我需要知道该财产是公共的还是受保护的。例如:

public string Name{get;set;}
protected  int Age{get;set;}

PropertyInfo类似乎没有公开有关该属性的信息。还有其他方法吗?

因为属性只是一对
get
/
set
方法的语法糖分,所以不存在属性反射的“可访问性”。相反,您必须分别找出
get
set
方法的可访问性级别。为此,使用和方法检索适当的
MethodInfo
对象,其中有各种
IsPrivate
IsPublic
和其他方法和属性。

您需要查看每个get&set方法的MethodInfo 例如:


似乎是IsFamily属性指示某个方法是否受保护。

为此编写了一个扩展方法:

    static void Main()
    {
        sample obj = new sample();
        Type t = obj.GetType();
        MethodInfo[] m = t.GetMethods();
        Console.WriteLine("Method Information:-\n\n");
        foreach (MethodInfo m1 in m)
            Console.WriteLine("Mthod name:" + m1.Name + "  \nMethod return type:" + m1.ReturnType + "\nIs staic:" + m1.IsStatic + "\nIs Public:" + m1.IsPublic + "\nIs Private:" + m1.IsPrivate);
        FieldInfo[] f = t.GetFields();
        Console.WriteLine("\n\nField Information:-\n\n");
        foreach(FieldInfo f1 in f)
            Console.WriteLine("Field name:" + f1.Name + "  \nField type:" + f1.FieldType + "\nIs staic:" + f1.IsStatic);
        Console.Read();
    }
public static class ReflectionExt
{
    public static readonly List<AccessModifier> AccessModifiers = new List<AccessModifier>
    {
        AccessModifier.Private, 
        AccessModifier.Protected, 
        AccessModifier.ProtectedInternal,
        AccessModifier.Internal,  
        AccessModifier.Public
    };

    public static AccessModifier Accessmodifier(this PropertyInfo propertyInfo)
    {
        if (propertyInfo.SetMethod == null)
            return propertyInfo.GetMethod.Accessmodifier();
        if (propertyInfo.GetMethod == null)
            return propertyInfo.SetMethod.Accessmodifier();
        var max = Math.Max(AccessModifiers.IndexOf(propertyInfo.GetMethod.Accessmodifier()),
            AccessModifiers.IndexOf(propertyInfo.SetMethod.Accessmodifier()));
        return AccessModifiers[max];
    }

    public static AccessModifier Accessmodifier(this MethodInfo methodInfo)
    {
        if (methodInfo.IsPrivate)
            return AccessModifier.Private;
        if (methodInfo.IsFamily)
            return AccessModifier.Protected;
        if (methodInfo.IsFamilyOrAssembly)
            return AccessModifier.ProtectedInternal;
        if (methodInfo.IsAssembly)
            return AccessModifier.Internal;
        if (methodInfo.IsPublic)
            return AccessModifier.Public;
        throw new ArgumentException("Did not find access modifier", "methodInfo");
    }
}

不要忘记
MethodInfo.IsFamilyOrAssembly
,它表示
受保护的内部
。另外,您可以删除列表并使用枚举的序号值来计算max:
return(AccessModifier)Math.max((int)property.GetMethod.AccessModifier(),(int)property.SetMethod.AccessModifier())
@MrLore nice catch,我已经更新了答案(您也可以做得更好)。请注意新的ish“private protected”访问修饰符。
public static class ReflectionExt
{
    public static readonly List<AccessModifier> AccessModifiers = new List<AccessModifier>
    {
        AccessModifier.Private, 
        AccessModifier.Protected, 
        AccessModifier.ProtectedInternal,
        AccessModifier.Internal,  
        AccessModifier.Public
    };

    public static AccessModifier Accessmodifier(this PropertyInfo propertyInfo)
    {
        if (propertyInfo.SetMethod == null)
            return propertyInfo.GetMethod.Accessmodifier();
        if (propertyInfo.GetMethod == null)
            return propertyInfo.SetMethod.Accessmodifier();
        var max = Math.Max(AccessModifiers.IndexOf(propertyInfo.GetMethod.Accessmodifier()),
            AccessModifiers.IndexOf(propertyInfo.SetMethod.Accessmodifier()));
        return AccessModifiers[max];
    }

    public static AccessModifier Accessmodifier(this MethodInfo methodInfo)
    {
        if (methodInfo.IsPrivate)
            return AccessModifier.Private;
        if (methodInfo.IsFamily)
            return AccessModifier.Protected;
        if (methodInfo.IsFamilyOrAssembly)
            return AccessModifier.ProtectedInternal;
        if (methodInfo.IsAssembly)
            return AccessModifier.Internal;
        if (methodInfo.IsPublic)
            return AccessModifier.Public;
        throw new ArgumentException("Did not find access modifier", "methodInfo");
    }
}
public enum AccessModifier
{
    Private,
    Protected,
    Internal,
    Public
}