特性



目录




自定义特性类

  特性是一种比较特殊的类,作为代码对象附加部分用于向运行时提供一些补充信息。

  主要有三个特征:

  • 从Attribute类派生
  • 名称一般以Attribute结尾
  • 声明特性类时必须在类上加AttributeUsage,用于标注当前声明的类应用于哪些对象
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method)]
public class MyDemoAttribute : Attribute
{
public string Description { get; set; }
}

public class OrderData
{
[MyDemo(Description = "订单 ID")]
public int OrdID { get; set; }

[MyDemo(Description = "添加时间")]
public DateTime AddTime { get; set; }

[MyDemo(Description = "计算折扣价")]
public double Compute(double q)
{
return q * 0.98d;
}
}


向特性类构造函数传递参数

  特性类若只有无参构造函数,应用时可以忽略小括号。若有有参构造函数,那么应在小括号中填上参数。

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
public class DoubleRangeAttribute : Attribute
{
public double Largest { get; }

public DoubleRangeAttribute(double largest)
{
Largest = largest;
}
}

[DoubleRange(700d)]
public class Test
{

}


同一对象上应用多个特性

  声明特性类时,​​AttributeUsage​​类的​​AllowMultiple​​属性用于设置是否允许在同一对象上应用多个特性实例,默认​​false​​。

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class CustomAttribute : Attribute
{
public string Ver { get; set; }
}

[Custom(Ver = "1.0.0.1"), Custom(Ver = "1.0.2.0")]
public class AppData
{

}


运行阶段对数据验证

  声明一个特性类

    [AttributeUsage(AttributeTargets.Property)]
public class MyAttribute : Attribute
{
public char StartChar { get; set; }
public int MaxLen { get; set; }
}


  把MyAttribute特性应用到测试类的RawName属性上,StartChar表示以“k”开头,MaxLen表示最大长度为7.

    public class Test
{
[My(StartChar = 'k', MaxLen = 7)]
public string RawName { get; set; }
}


  需要用到反射,通过Type类得到对象的各种信息,通过​​GetCustomAttribute​​扩展方法得到已应用的特性实例。

    class Program
{
static void Main(string[] args)
{
Test v = new Test { RawName = "k003d6ex915f" };
// 调用方法进行属性值验证
bool b = CheckTest(v, nameof(Test.RawName));
if (b)
Console.WriteLine("验证通过。");
else
Console.WriteLine("验证失败。");

Console.Read();
}

static bool CheckTest(Test t, string property)
{
// 获取类型信息
Type type = t.GetType();
// 查找属性成员
PropertyInfo prop = type.GetProperty(property, BindingFlags.Public | BindingFlags.Instance);
if (prop == null)
{
return false;
}
// 获取特性
MyAttribute att = prop.GetCustomAttribute<MyAttribute>();
// 获取实例的属性值
string value = prop.GetValue(t) as string;
if (string.IsNullOrEmpty(value))
return false;
// 进行验证
if (value.StartsWith(att.StartChar) == false)
return false;
if (value.Length > att.MaxLen)
return false;

return true;
}
}


返回值上应用特性

    [AttributeUsage(AttributeTargets.ReturnValue)]
public class CheckSumAttribute : Attribute
{

}
    [return: CheckSum]
static string SaySomething() => "Hello";


作者:一纸年华​​​