开发者

Detect access modifier type on a property using Reflection

I have written some code to look at properties using reflection. I have retrieved a list of properties from the class using reflection.

However I need to find out if the property is开发者_开发问答 public or protected. eg:

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

The PropertyInfo class does not seem to expose this information about the property. Is there another way to do this?


Since properties are just syntactic sugar over a pair of get/set methods, there's no such thing as "accessibility" of a property reflection-wise. Rather, you'll have to find out accessibility levels of get and set methods separately. To that end, retrieve appropriate MethodInfo objects with GetGetMethod and GetSetMethod methods, and from there are various IsPrivate, IsPublic and other methods and properties.


You need to look at the methodInfo of each get & set method eg :

PropertyInfo pi = ...;
bool isPublic = pi.GetGetMethod(true).IsPublic;
bool isProtected= pi.GetGetMethod(true).IsFamily;

It seems to be the IsFamily property that indicates if a method is protected..


Wrote an extension method for this:

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
}


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


//.NET 6.0
namespace Test
{
    public enum AccessModifier
    {
        None,
        Private,
        Protected,
        ProtectedInternal,
        Internal,
        Public
    }

    class ReflectProperties
    {
        public class PersonInfo
        {
            public string FirstName { get; set; }
            internal string LastName { get; set; }
            protected int Age { get; set; }
            private string PhoneNumber { get; set; }
            protected internal Email {get; set; }
        }

        public static void WriteProperties()
        {
            var t = typeof(TestProperties).GetTypeInfo();

            foreach (var p in t.DeclaredProperties)
            {
                Console.WriteLine($"Property name: {p.Name}");                
                Console.WriteLine($"Accessibility: {p.GetAccessmodifier()}");
                Console.WriteLine();
            }
        }
    }    
       
    public static class MyExtensions
    {
        public static AccessModifier GetAccessmodifier(this PropertyInfo propertyInfo)
        {
            if (propertyInfo == null)
                throw new ArgumentNullException(nameof(propertyInfo));

            var setterAccessibility = propertyInfo.GetSetMethod(true)?.GetAccessmodifier() ?? AccessModifier.None;
            var getterAccessibility = propertyInfo.GetGetMethod(true)?.GetAccessmodifier() ?? AccessModifier.None;
            return Max(setterAccessibility, getterAccessibility);
        }

        private static AccessModifier Max(AccessModifier mod1, AccessModifier mod2)
        {
            if (mod1 == mod2 && mod2 == AccessModifier.None)
                throw new ArgumentException();            

            if (mod1 > mod2)
                return mod1;

            if (mod2 > mod1)
                return mod2;

            return mod1;
        }

        public static AccessModifier GetAccessmodifier(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");
        }
    }

    internal class Program
    {
        static void Main(string[] args)
        {
            ReflectProperties.WriteProperties();
        }
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜