C# 特性(Attribute)、反射、读取特性、分析特性的示例

2019年12月29日 2848点热度 2人点赞 0条评论
内容纲要

通过反射获取到属性名称以及特性后,要获取属性的值。

        static void Main(string[] args)
        {
            Test test = new Test()
            {
                A = 13510377651,
                B = 1,
                C = 13510399648
            };
            Type type = test.GetType();

            // 获取类的属性列表
            PropertyInfo[] properties = type.GetProperties();

            foreach (PropertyInfo item in properties)
            {
                MyAttribute att = (MyAttribute)Attribute.GetCustomAttribute(item, typeof(MyAttribute));
                if (att != null)
                {
                    Console.WriteLine(att.Name + "|" + item.Name + "|" + item.GetValue(test) + "|是否属于手机号:" + IsValid(item.PropertyType, item.GetValue(test)));
                }

            }
            Console.ReadKey();
        }

        private static bool IsValid(Type type, object value)
        {

            if (type != typeof(long))
                return false;

            long phone;
            bool num = long.TryParse(new ReadOnlySpan<char>(value.ToString().ToCharArray()), out phone);
            if (num == false)
                return false;

            if (phone < 100_000_000_00)
                return false;

            return true;
        }
    }
    public class Test
    {
        [My("1")]
        public long A { get; set; }
        [My("2")]
        public long B { get; set; }
        [My("3")]
        public long C { get; set; }
    }

    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter,
         AllowMultiple = false)]
    public class MyAttribute : Attribute
    {
        public string Name { get; set; }
        public MyAttribute(string name)
        {
            Name = name;
        }
    }

输出结果

1|A|13510377651|是否属于手机号:True
2|B|1|是否属于手机号:False
3|C|13510399648|是否属于手机号:True

一个类型反射后的使用方法如下

//使用方式:
//访问或修改类型的实例字段myField
MyClass myObj = new MyClass() { myField = 1 }; //创建实例
Type myType = typeof(MyClass); //获取类型,或myObj.GetType()
FieldInfo fieldInfo = myType.GetField("myField"); //获取类型中指定的字段信息
Console.WriteLine((int)fieldInfo.GetValue(myObj)); //1,获取实例字段的值
fieldInfo.SetValue(myObj, 2); //给实例字段赋值
//访问或修改类型的静态字段myStaticField
FieldInfo staticFieldInfo = myType.GetField("myStaticField"); //获取类型中指定的字段信息
Console.WriteLine(staticFieldInfo.GetValue(null)); //0,获取静态字段的值
staticFieldInfo.SetValue(null, 2); //给静态字段赋值

public class MyClass
{
    public int MyProperty { get; set; }
    public static int MyStaticProperty { get; set; }
}

//使用方式:
//访问或修改类型的实例属性MyProperty
MyClass myObj = new MyClass() { MyProperty = 1 }; //创建实例
Type myType = typeof(MyClass); //获取类型,或myObj.GetType()
PropertyInfo propertyInfo = myType.GetProperty("MyProperty"); //获取类型中指定的属性信息
Console.WriteLine((int)propertyInfo.GetValue(myObj, null)); //1,获取实例属性的值
propertyInfo.SetValue(myObj, 2, null); //给实例属性赋值

//访问或修改类型的静态属性MyStaticProperty
PropertyInfo staticPropertyInfo = myType.GetProperty("MyStaticProperty"); //获取类型中指定的属性信息
Console.WriteLine(staticPropertyInfo.GetValue(null, null)); //0,获取静态属性的值
staticPropertyInfo.SetValue(null, 2); //给静态属性赋值

※在使用反射给属性赋值时,如果该属性不具有set访问器,则会抛出异常ArgumentException;

痴者工良

高级程序员劝退师

文章评论