// // Access modifiers // We use reflection to test that the flags are the correct ones // using System; using System.Reflection; [AttributeUsage (AttributeTargets.Class)] public class TypeCheckAttribute : Attribute { public TypeCheckAttribute () { } } [AttributeUsage (AttributeTargets.Property)] public class PropertyCheckAttribute : Attribute { public PropertyCheckAttribute () { } } [AttributeUsage (AttributeTargets.Method)] public class AccessorCheckAttribute : Attribute { MethodAttributes flags; public AccessorCheckAttribute (MethodAttributes flags) { this.flags = flags; } public MethodAttributes Attributes { get { return flags; } } } public class Test { public static int Main (string [] args) { Type t = typeof (A); foreach (PropertyInfo pi in t.GetProperties ()) { object [] attrs = pi.GetCustomAttributes (typeof (PropertyCheckAttribute), true); if (attrs == null) return 0; MethodInfo get_accessor, set_accessor; get_accessor = pi.GetGetMethod (true); set_accessor = pi.GetSetMethod (true); if (get_accessor != null) CheckFlags (pi, get_accessor); if (set_accessor != null) CheckFlags (pi, set_accessor); } return 0; } static void CheckFlags (PropertyInfo pi, MethodInfo accessor) { object [] attrs = accessor.GetCustomAttributes (typeof (AccessorCheckAttribute), true); if (attrs == null) return; AccessorCheckAttribute accessor_attr = (AccessorCheckAttribute) attrs [0]; MethodAttributes accessor_flags = accessor.Attributes; if ((accessor_flags & accessor_attr.Attributes) == accessor_attr.Attributes) Console.WriteLine ("Test for {0}.{1} PASSED", pi.Name, accessor.Name); else { string message = String.Format ("Test for {0}.{1} INCORRECT: MethodAttributes should be {2}, but are {3}", pi.Name, accessor.Name, accessor_attr.Attributes, accessor_flags); throw new Exception (message); } } } [TypeCheck] public class A { const MethodAttributes flags = MethodAttributes.HideBySig | MethodAttributes.SpecialName; [PropertyCheck] public int Value1 { [AccessorCheck (flags | MethodAttributes.Public)] get { return 0; } [AccessorCheck (flags | MethodAttributes.Public)] set { } } [PropertyCheck] public int Value2 { [AccessorCheck (flags | MethodAttributes.Public)] get { return 0; } [AccessorCheck (flags | MethodAttributes.FamORAssem)] protected internal set { } } [PropertyCheck] public int Value3 { [AccessorCheck (flags | MethodAttributes.Public)] get { return 0; } [AccessorCheck (flags | MethodAttributes.Family)] protected set { } } [PropertyCheck] public int Value4 { [AccessorCheck (flags | MethodAttributes.Assembly)] internal get { return 0; } [AccessorCheck (flags | MethodAttributes.Public)] set { } } [PropertyCheck] public int Value5 { [AccessorCheck (flags | MethodAttributes.Public)] get { return 0; } [AccessorCheck (flags | MethodAttributes.Private)] private set { } } }