C#特性Attribute应用
应用
利用反射获取Attribute信息并执行方法
using System;
using System.Reflection;
// 自定义属性类
/// <summary>
/// 自定义特性
/// AllowMultiple =true:标记在特性上的特性,其实是对特性的一种约束;
/// Inherited =true:约束当前特性是否可以继承
/// AttributeTargets.All:当前特性可以标记在所有的元素上
/// AttributeUsage:在定义特性的时候,对特性的一种约束
/// </summary>
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)]
public class CustomAttribute : Attribute
{
public CustomAttribute()
{
}
public CustomAttribute(int id)
{
}
public CustomAttribute(string name)
{
}
public CustomAttribute(int id, string name)
{
this.Id = id;
this.Name = name;
}
public string Description;
public int Id { get; set; }
public string Name { get; set; }
public void Do()
{
Console.WriteLine($"Doing something with Id={Id} and Name={Name}");
}
}
// 一个示例类,应用了自定义属性
[CustomAttribute(1, "ClassAttribute")]
public class MyClass
{
[CustomAttribute(2, "PropertyAttribute")]
public int MyProperty { get; set; }
[CustomAttribute(3, "FieldAttribute")]
public string MyField;
[CustomAttribute(4, "MethodAttribute")]
public void MyMethod()
{
Console.WriteLine("Inside MyMethod");
}
}
class Program
{
// ReflectionAttribute 方法的定义
public static void ReflectionArrtibute<T>(T t) where T : class
{
Type type = t.GetType();//通过参数来获取Type类型
if (type.IsDefined(typeof(CustomAttribute), true)) //反射调用特性,记得一定要先判断,然后再获取
{
foreach (CustomAttribute attribute in type.GetCustomAttributes()) //把所有标记的特性都实例化了
{
Console.WriteLine($"attribute.Id={attribute.Id}");
Console.WriteLine($"attribute.Name={attribute.Name}");
attribute.Do();
}
///循环获取所有的属性上标记的特性,调用特性中的元素
foreach (PropertyInfo prop in type.GetProperties())
{
if (prop.IsDefined(typeof(CustomAttribute), true))
{
foreach (CustomAttribute attribute in prop.GetCustomAttributes(typeof(CustomAttribute))) //把所有标记的特性都实例化了
{
Console.WriteLine($"attribute.Id={attribute.Id}");
Console.WriteLine($"attribute.Name={attribute.Name}");
attribute.Do();
}
}
}
///循环获取所有的字段上标记的特性,调用特性中的元素
foreach (FieldInfo field in type.GetFields())
{
if (field.IsDefined(typeof(CustomAttribute), true))
{
foreach (CustomAttribute attribute in field.GetCustomAttributes(typeof(CustomAttribute))) //把所有标记的特性都实例化了
{
Console.WriteLine($"attribute.Id={attribute.Id}");
Console.WriteLine($"attribute.Name={attribute.Name}");
attribute.Do();
}
}
}
///循环获取所有方法上标记的特性,调用特性中的元素
foreach (MethodInfo method in type.GetMethods())
{
if (method.IsDefined(typeof(CustomAttribute), true))
{
foreach (CustomAttribute attribute in method.GetCustomAttributes(typeof(CustomAttribute))) //把所有标记的特性都实例化了
{
Console.WriteLine($"attribute.Id={attribute.Id}");
Console.WriteLine($"attribute.Name={attribute.Name}");
attribute.Do();
}
}
}
}
}
static void Main(string[] args)
{
// 创建 MyClass 的实例
var myClassInstance = new MyClass();
// 调用 ReflectionAttribute 方法,传递 MyClass 的实例作为参数
ReflectionArrtibute(myClassInstance);
}
}
输出:
attribute.Id=1
attribute.Name=ClassAttribute
Doing something with Id=1 and Name=ClassAttribute
attribute.Id=2
attribute.Name=PropertyAttribute
Doing something with Id=2 and Name=PropertyAttribute
attribute.Id=3
attribute.Name=FieldAttribute
Doing something with Id=3 and Name=FieldAttribute
attribute.Id=4
attribute.Name=MethodAttribute
Doing something with Id=4 and Name=MethodAttribute
将枚举值的中文扩展信息添加到Attribute
//新增ExplainAttribute
using System.ComponentModel.DataAnnotations;
using System;
using System.Reflection;
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)]
public class ExplainAttribute : Attribute
{
public string Explain { get; private set; }
public ExplainAttribute(string explain)
{
this.Explain = explain;
}
}
//创建枚举
public enum GameState
{
[ExplainAttribute("开始")]
Start,
[ExplainAttribute("暂停")]
Stop,
[ExplainAttribute("继续")]
GoOn
}
//获取Attribute信息
public static class ExplainExtension
{
public static string GetExplain(this Enum @enum)
{
Type type = @enum.GetType();
FieldInfo field = type.GetField(@enum.ToString());
if (field != null)
{
if (field.IsDefined(typeof(ExplainAttribute), true))
{
ExplainAttribute attribute = field.GetCustomAttribute<ExplainAttribute>();
return attribute.Explain;
}
}
return @enum.ToString();
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(GameState.Start.GetExplain());// 输出:开始
}
}
验证合法值
using System;
// 自定义属性类
public class ValidateAttribute : Attribute
{
public string ErrorMessage { get; set; }
public ValidateAttribute(string errorMessage)
{
ErrorMessage = errorMessage;
}
public virtual bool IsValid(object value)
{
// 这里可以编写验证逻辑,这个示例中只是简单地返回 true,表示始终验证通过
return true;
}
}
// 自定义属性类的派生类,用于具体的验证逻辑
public class RangeAttribute : ValidateAttribute
{
public int Min { get; }
public int Max { get; }
public RangeAttribute(int min, int max, string errorMessage) : base(errorMessage)
{
Min = min;
Max = max;
}
public override bool IsValid(object value)
{
if (value is int intValue)
{
return intValue >= Min && intValue <= Max;
}
return false;
}
}
// 需要验证的类
public class Person
{
[Range(18, 60, "Age must be between 18 and 60.")]
public int Age { get; set; }
}
class Program
{
static void Main(string[] args)
{
// 创建一个 Person 实例
var person = new Person();
// 尝试设置不合法的年龄值
person.Age = 16;
// 验证年龄是否合法
var ageProperty = typeof(Person).GetProperty("Age");
var rangeAttribute = (RangeAttribute)ageProperty.GetCustomAttributes(typeof(RangeAttribute), false)[0];
if (!rangeAttribute.IsValid(person.Age))
{
Console.WriteLine(rangeAttribute.ErrorMessage); // 输出错误消息
}
else
{
Console.WriteLine("Age is valid."); // 年龄合法
}
}
}