C # custom properties (the Attribute) Detailed

What are the characteristics


Custom Properties: Allows the common language runtime add descriptive statement similar keywords, called the attribute, its program elements are labeled, such as type, fields, methods, and attributes. Metadata attribute and .NetFramework files stored together, it can be used to describe your code at runtime or to affect application behavior when the program is running.

How to write custom properties


To help you understand the features of the custom, we look first of all with the compiler encounters code an application of custom properties, it is how to deal with, to test Model for example, if a C # property declaration, as follows

    public class User
    {
        /// <summary>
        /// 名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 邮箱
        /// </summary>
        [EmailAttribute]
        public string Email { get; set; }

        /// <summary>
        /// 薪水
        /// </summary>
        [LenghtAttribute(10000, 100000)]
        public decimal Salary { get; set; }
    }

    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = = false, Inherited = false)]
    public class LenghtAttribute
    {
        private int _minLenght = 0;
        private int _maxLenght = 0;
        public LenghtAttribute(int minLenght, int maxLenght)
        {
            _minLenght = minLenght;
            _maxLenght = maxLenght;
        }
    }

When the compiler found that application of a FiedlName property characteristics, before the string is appended to the name Attribute, to form a composite name FieldNameAttribute, then all namespaces search path search has designated the name of the class, it is noted that If the compiler has found a marked characteristic data item, and this is the end of the Attribute name, the compiler will not be added to a combination of the names of characters, so this is what we use characteristic fields are marked compiler will default Attribute character the reason the light blue font to display
after the compiler will find the class containing the name, and this class is derived directly or indirectly from System.Attribute. The compiler also believe that this class contains information usage control features. especially

  1. Properties can be applied to those types of program elements
  2. Whether it can be applied multiple times to the same program element
  3. Characteristics when applied to a class or interface, by the derived classes inherit the classes and interfaces
  4. Which mandatory and optional parameters have this feature

If you can not find the specified characteristics of the class, or find a characteristic class, but the mode of information use features and characteristics of the class does not match, the compiler will generate an error, such as the characteristic properties of the specified class can only be applied on the structure, but we used in the field or class, the compiler will generate an error


A specified class AttributeUsage

First, the characteristics of the class itself is a need to mark the characteristic properties --system.AttributeUsage, AttributeUsage to represent our properties can be applied to those types of program elements, this parameter is mandatory in AttributeUsage parameter is an enumeration type type AttributeTargets. details as follows


1.Assembly = 0x1,
2.Module = 0x2,
3.Class = 0x4,
4.Struct = 0x8,
5.Enum = 0x10,
6.Constructor = 0x20,
7.Method = 0x40,
8.Property = 0x80,
9.Field = 0x100,
10.Event = 0x200,
11.Interface = 0x400,
12.Parameter = 0x800,
13.Delegate = 0x1000,
14.ReturnValue = 0x2000,
15.GenericParameter = 0x4000,
16.All = 0x7FFF


If you want to know the corresponding enumeration type can be seen in detail under go System.AttributeTargets, here is not introduced one by one to tell you
but we need to note that there are in the above enumerated type enumeration values do not correspond to any two program elements, and module assembly
characteristics may be applied to the entire assembly or module, instead of applying the code in one element, in this case, this feature can be placed anywhere in the source code, but requires the use of assembly and Module, worded as follows

    public class User
    {
        [Assembly: FieldNameAttribute(Parameters)]
        [Module: FieldNameAttribute(Parameters)]
    }

There are also two properties AllowMultiple and Inherited
AllowMultiple indicates whether this feature can be used many times to the same one,
Inherited a characteristic on application to the class or interface can be automatically applied to all derived classes and interfaces, if applied to the methods and the attributes may be automatically applied to the override of the methods and properties,

Second, the specified parameters

Next to tell you how to customize the characteristics of acceptable parameters.
The compiler checks the parameters passed to the characteristic, and the characteristic look constructor with these types of parameters, if the compiler finds such a configuration, the compiler will specify the metadata that was passed to the assembly, and vice versa will generate a compiler error.

Third, the specific characteristics of the optional parameters

In AttributeUsaege characteristics, you can use another syntax, adding an optional parameter to the characteristics, such syntax specifies an optional parameter names and values, which function by a common characteristic of the class properties and fields.

Fourth, the complete code

  public abstract class BaseAttribute : Attribute
    {
        /// <summary>
        /// 验证
        /// </summary>
        /// <param name="oValue"></param>
        /// <returns></returns>
        public abstract bool Validate(object oValue);
    }
    /// <summary>
    /// 特性扩展
    /// </summary>
    public static class AttributeExtend
    {
        /// <summary>
        /// 验证
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static bool Validate<T>(T t)
        {
            Type type = t.GetType();
            foreach (var prop in type.GetProperties())
            {
                if (prop.IsDefined(typeof(BaseAttribute), true))
                {
                    var oValue = prop.GetValue(t, null);

                    foreach (BaseAttribute item in prop.GetCustomAttributes(typeof(BaseAttribute), true))//获取字段所有的特性
                    {
                        if (!item.Validate(oValue))
                        {
                            return false;
                        }
                    }
                }
            }
            return true;
        }
    }

    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = = false, Inherited = false)]
    public class LenghtAttribute : BaseAttribute
    {
        private int _minLenght = 0;
        private int _maxLenght = 0;
        public LenghtAttribute(int minLenght, int maxLenght)
        {
            _minLenght = minLenght;
            _maxLenght = maxLenght;
        }
        public override bool Validate(object oValue)
        {
            decimal.TryParse(oValue.ToString(), out var minParam);
            decimal.TryParse(oValue.ToString(), out var maxParam);
            if (oValue != null)
            {
                return minParam >= _minLenght && maxParam <= _maxLenght;
            }
            return true;
        }
    }
    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = = false, Inherited = false)]
    public class EmailAttribute : BaseAttribute
    {
        public override bool Validate(object oValue)
        {
            if (oValue != null)
            {
                Regex r = new Regex(@"^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$");
                return r.IsMatch(oValue.ToString());
            }
            return true;

        }
    }
     static void Main(string[] args)
        {
            var user = new User { Name = "张三", Email = "[email protected]", Salary = 60000.1M };
            var result = AttributeExtend.Validate<User>(user);
            Console.WriteLine("Hello World!");
            Console.ReadKey();
        }

If not quite understand where to put it or there is an error, please correct me
if you like, you may wish to point a collection of praise about it

Guess you like

Origin www.cnblogs.com/ancold/p/11931435.html