吉林市做网站的科技,四川重大新闻事件,网站模板站扩容,关注公众号赚钱语法
原则 自定义特性必须继承自System.Attribute类#xff1b; AttributeUsage属性来指定特性的使用范围和是否允许重复等#xff1b; 在特性类中定义属性#xff0c;这些属性将用于存储特性值。
示例
using System;// 定义一个自定义特性类
[Attribute…语法
原则 自定义特性必须继承自System.Attribute类 AttributeUsage属性来指定特性的使用范围和是否允许重复等 在特性类中定义属性这些属性将用于存储特性值。
示例
using System;// 定义一个自定义特性类
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple true)]
public class CustomAttribute : Attribute
{// 特性属性public string Description { get; set; }public int Version { get; set; }// 特性构造函数public CustomAttribute(string description, int version){Description description;Version version;}
}// 使用自定义特性
[Custom(This is a sample class, 1)]
public class SampleClass
{[Custom(This is a sample method, 1)]public void SampleMethod(){// 方法实现}
}class Program
{static void Main(){// 获取SampleClass类的特性信息var classAttributes typeof(SampleClass).GetCustomAttributes(typeof(CustomAttribute), false);foreach (CustomAttribute attr in classAttributes){Console.WriteLine($Class Description: {attr.Description}, Version: {attr.Version});}// 获取SampleMethod方法的特性信息var methodAttributes typeof(SampleClass).GetMethod(SampleMethod).GetCustomAttributes(typeof(CustomAttribute), false);foreach (CustomAttribute attr in methodAttributes){Console.WriteLine($Method Description: {attr.Description}, Version: {attr.Version});}}
}AttributeUsage中的AllowMultiple属性默认值为false它决定同种特性类型的实例能否在同一个目标上多次使用比如在类中的同一个属性上。
特性声明代码
using System;
using System.Reflection;namespace Model.Common
{/// summary/// 用于生成SQLServer数据库查询的like条件/// /summary[AttributeUsage(AttributeTargets.Property, AllowMultiple false)]public class SqlLikeAttribute : Attribute{/// summary/// 数据库字段名/// /summarypublic string FieldName { get; set; }public SqlLikeAttribute(string fidleName){FieldName fidleName;}}/// summary/// 用于生成SQLServer数据库查询的、、、、条件/// /summary[AttributeUsage(AttributeTargets.Property,AllowMultiple false)]public class SqlRangeAttribute: Attribute{/// summary/// 数据库字段名/// /summarypublic string FieldName { get; set; }/// summary/// 取值范围、、、、/// /summarypublic string Range { get; set; }public SqlRangeAttribute(string fidleName, string range){FieldName fidleName;Range range;}}/// summary/// 用于生成SQLServer数据库查询的between条件/// /summary[AttributeUsage(AttributeTargets.Property, AllowMultiple false)]public class SqlBetweenAttribute : Attribute{/// summary/// 数据库字段名/// /summarypublic string FieldName { get; set; }/// summary/// 查询条件实体中的另一个字段名/// /summarypublic string AnotherFieldName { get; set; }/// summary/// 是否是开始/// /summarypublic bool IsStart { get; set; }public Object Value { get; set; }public SqlBetweenAttribute(string fidleName, string anotherFieldName, bool start true){FieldName fidleName;AnotherFieldName anotherFieldName;IsStart start;}}/// summary/// 用于生成SQLServer数据库查询的条件有SqlIgnoreAttribute修饰的属性直接忽略掉/// /summary[AttributeUsage(AttributeTargets.Property, AllowMultiple false)]public class SqlIgnoreAttribute : Attribute{}/// summary/// 测试/// /summarypublic class AttributeTest{public static void Test(){TestModel testModel new TestModel(){ID 1,Name test,Begin DateTime.Now,End DateTime.Now.AddDays(1),};Type type testModel.GetType();PropertyInfo[] infos type.GetProperties();foreach (PropertyInfo info in infos){SqlBetweenAttribute attr (SqlBetweenAttribute)info.GetCustomAttribute(typeof(SqlBetweenAttribute), false);if (attr ! null){string field attr.FieldName;}}}}public class TestModel{public int ID { get; set; }public string Name { get; set; }[SqlBetween(field, End)]public DateTime Begin { get; set; }[SqlBetween(field, Begin, false)]public DateTime End { get; set; }}
}使用特性
/// summary/// 从实体中获取属性值不为空的属性和值用于数据库Select的Where条件/// 暂时只支持int、string、double、DateTime/// 要求数值类型默认为-1/// /summary/// param namedata/param/// param nameprefix前缀/param/// returns/returnspublic static Liststring GetPropertyValueNotNullForSelectWhere(this object data, string prefix){string item ;Liststring items new Liststring();Dictionarystring, SqlBetweenAttribute dic new Dictionarystring, SqlBetweenAttribute();DateTime dateTime new DateTime(1, 1, 1, 0, 0, 0);PropertyInfo[] propertyInfos data.GetType().GetProperties();foreach (PropertyInfo propertyInfo in propertyInfos){if (propertyInfo.Name.ToUpper() ID)continue;item ;object obj propertyInfo.GetValue(data, null);switch (propertyInfo.PropertyType.FullName){case System.Int32:if (Convert.ToInt32(obj) -1)continue;item $ and {prefix}{propertyInfo.Name}{Convert.ToInt32(obj)};break;case System.String:if (Convert.ToString(obj) )continue;item $ and {prefix}{propertyInfo.Name}{Convert.ToString(obj)};break;case System.Double:if (Convert.ToDouble(obj) -1)continue;item $ and {prefix}{propertyInfo.Name}{Convert.ToDouble(obj)};break;case System.Decimal:if (Convert.ToDecimal(obj) -1)continue;item $ and {prefix}{propertyInfo.Name}{Convert.ToDecimal(obj)};break;case System.DateTime:obj propertyInfo.GetValue(data, null);if (Convert.ToDateTime(obj) dateTime)continue;item $ and {prefix}{propertyInfo.Name}{Convert.ToDateTime(obj)};break;}//if(!CheckAttrSqlBetween(propertyInfo, obj, ref dic, ref item))// continue;CheckAttrSqlRange(propertyInfo, obj, ref item, prefix);CheckAttrSqlLike(propertyInfo, obj, ref item, prefix);if (!CheckAttrSqlIgnore(propertyInfo, obj, ref item))continue;items.Add(item);}return items;}/// summary/// 检查属性是否被SqlBetween特性修饰并处理/// /summary/// param namepropertyInfo实体的属性对象/param/// param nameobj属性的值/param/// param namedic暂存特性的字典/param/// param nameitem/param/// returnstrue 表示需要把item加到Liststring中/returnsstatic bool CheckAttrSqlBetween(PropertyInfo propertyInfo, object obj, ref Dictionarystring, SqlBetweenAttribute dic, ref string item){SqlBetweenAttribute attr (SqlBetweenAttribute)propertyInfo.GetCustomAttribute(typeof(SqlBetweenAttribute), false);if (attr null)return true;attr.Value obj;if (!dic.ContainsKey(attr.AnotherFieldName)){ //缺少另外一个先缓存dic.Add(attr.AnotherFieldName, attr);return false;}else{SqlBetweenAttribute _attr dic[attr.AnotherFieldName];dic.Remove(attr.AnotherFieldName);SqlBetweenAttribute attrb attr.IsStart ? attr : _attr;SqlBetweenAttribute attre attr.IsStart ? _attr : attr;switch (propertyInfo.PropertyType.FullName){case System.Int32:case System.Double:case System.Decimal:item $ and {attr.FieldName} between {attrb.Value} and {attre.Value};break;case System.String:case System.DateTime:item $ and {attr.FieldName} between {attrb.Value} and {attre.Value};break;}return true;}}/// summary/// 检查属性是否被SqlRange特性修饰并处理/// /summary/// param namepropertyInfo/param/// param nameobj/param/// param nameitem/param/// returns/returnsstatic void CheckAttrSqlRange(PropertyInfo propertyInfo, object obj, ref string item, string prefix){SqlRangeAttribute attr (SqlRangeAttribute)propertyInfo.GetCustomAttribute(typeof(SqlRangeAttribute), false);if (attr null)return;switch (propertyInfo.PropertyType.FullName){case System.Int32:case System.Double:case System.Decimal:item $ and {prefix}{attr.FieldName} {attr.Range} {obj} ;break;case System.String:case System.DateTime:item $ and {prefix}{attr.FieldName} {attr.Range} {obj} ;break;}return;}/// summary/// 检查属性是否被SqlLike特性修饰并处理/// /summary/// param namepropertyInfo/param/// param nameobj/param/// param nameitem/paramstatic void CheckAttrSqlLike(PropertyInfo propertyInfo, object obj, ref string item, string prefix){SqlLikeAttribute attr (SqlLikeAttribute)propertyInfo.GetCustomAttribute(typeof(SqlLikeAttribute), false);if (attr null)return;switch (propertyInfo.PropertyType.FullName){case System.String:item $ and ({prefix}{attr.FieldName} like %{obj}% or {prefix}{attr.FieldName}{obj}) ;break;}return;}/// summary/// 检查属性是否被SqlIgnoreAttribute特性修饰如果修饰则不加入到Where条件中/// /summary/// param namepropertyInfo/param/// param nameobj/param/// param nameitem/param/// returns/returnsstatic bool CheckAttrSqlIgnore(PropertyInfo propertyInfo, object obj, ref string item){SqlIgnoreAttribute attr (SqlIgnoreAttribute)propertyInfo.GetCustomAttribute(typeof(SqlIgnoreAttribute), false);if (attr null)return true;elsereturn false;}