C# 特性

特性是一个继承或者间接继承Attribute的类

通常用attribute结尾,那么在使用的时候,可以去掉这个结尾

1. 声明特性

复制代码
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
    public class TableAttribute : Attribute
    {
        private string _TableName = null;

        public TableAttribute(string tableName)
        {
            this._TableName = tableName;
        }

        public string GetTableName()
        {
            return this._TableName;
        }

    }
复制代码
复制代码
[AttributeUsage(AttributeTargets.Property)]
    public class IntValidateAttribute : Attribute
    {

        private int _Min = 0;
        private int _Max = 0;

        public IntValidateAttribute(int min, int max)
        {
            this._Min = min;
            this._Max = max;
        }

        public bool Validate(int num)
        {
            return num > this._Min && num < this._Max;
        }


    }
复制代码

2.  添加特性标记

复制代码
[Table("User")]

    public class UserModel
    {
        //public string TableName = "User";

        [IntValidateAttribute(0, 10000)]
        //[IntValidateAttribute(2, 5000)]
        public int Id { get; set; }

    }
复制代码

3.  添加应用该特性处理代码

复制代码
      /// <summary>
        /// 根据类型获取表名称  扩展方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public static string GetTableName<T>(this T t) where T : new()
        {
            Type type = t.GetType();
            object[] oAttributeList = type.GetCustomAttributes(true);
            foreach (var item in oAttributeList)
            {
                if (item is TableAttribute)
                {
                    TableAttribute attribute = item as TableAttribute;
                    return attribute.GetTableName();
                }
            }
            return type.Name;
        }
复制代码
复制代码
       /// <summary>
        /// 校验而且保存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        public static void Save<T>(T t)
        {
            bool isSafe = true;

            Type type = t.GetType();

            foreach (var property in type.GetProperties())
            {
                object[] oAttributeList = property.GetCustomAttributes(true);
                foreach (var item in oAttributeList)
                {
                    if (item is IntValidateAttribute)
                    {
                        IntValidateAttribute attribute = item as IntValidateAttribute;
                        isSafe = attribute.Validate((int)property.GetValue(t));
                    }
                }
                if (!isSafe)
                    break;
            }

            if (isSafe)
                Console.WriteLine("保存到数据库");
            else
                Console.WriteLine("数据不合法");
        }
复制代码

 

4.  调用方法,使用该特性

复制代码
class Program
    {
        static void Main(string[] args)
        {
            try
            {
                UserModel user = new UserModel();
                user.Id = 1;
                string name = user.GetTableName<UserModel>();

                BaseDAL.Save<UserModel>(user);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.Read();
        }
    }
复制代码

  

下面给特性应用的几个示例

示例1

复制代码
    /// <summary>
    /// 是给枚举用  提供一个额外信息
    /// </summary>
    [AttributeUsage(AttributeTargets.Enum | AttributeTargets.Field)]
    public class RemarkAttribute : Attribute
    {
        public RemarkAttribute(string remark)
        {
            this.Remark = remark;
        }

        public string Remark { get; private set; }
    }

复制代码
复制代码
    public static class RemarkExtend
    {
        /// <summary>
        /// 扩展方法
        /// </summary>
        /// <param name="enumValue"></param>
        /// <returns></returns>
        public static string GetRemark(this Enum enumValue)
        {
            Type type = enumValue.GetType();
            FieldInfo field = type.GetField(enumValue.ToString());
            if (field.IsDefined(typeof(RemarkAttribute), true))
            {
                RemarkAttribute remarkAttribute = (RemarkAttribute)field.GetCustomAttribute(typeof(RemarkAttribute));
                return remarkAttribute.Remark;
            }
            else
            {
                return enumValue.ToString();
            }
        }
    }
复制代码

 

示例2

复制代码
    public abstract class AbstractValidateAttribute : Attribute
    {
        public abstract bool Validate(object oValue);
    }

    public class LongValidateAttribute : AbstractValidateAttribute
    {
        private long _lMin = 0;
        private long _lMax = 0;
        public LongValidateAttribute(long lMin, long lMax)
        {
            this._lMin = lMin;
            this._lMax = lMax;
        }

        public override bool Validate(object oValue)
        {
            return this._lMin < (long)oValue && (long)oValue < this._lMax;
        }
    }
    public class RequirdValidateAttribute : AbstractValidateAttribute
    {
        public override bool Validate(object oValue)
        {
            return oValue != null;
        }
    }
复制代码
复制代码
    public class DataValidate
    {
        public static bool Validate<T>(T t)
        {
            Type type = t.GetType();
            bool result = true;
            foreach (var prop in type.GetProperties())
            {
                if (prop.IsDefined(typeof(AbstractValidateAttribute), true))
                {
                    object item = prop.GetCustomAttributes(typeof(AbstractValidateAttribute), true)[0];
                    AbstractValidateAttribute attribute = item as AbstractValidateAttribute;
                    if (!attribute.Validate(prop.GetValue(t)))
                    {
                        result = false;
                        break;
                    }
                }
            }
            return result;
        }
    }
复制代码

 

posted @   明志德道  阅读(468)  评论(0编辑  收藏  举报
编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
点击右上角即可分享
微信分享提示