C#特性Attribute应用
应用
利用反射获取Attribute信息并执行方法
using System;
using System.Reflection;
[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
{
public static void ReflectionArrtibute<T>(T t) where T : class
{
Type type = t.GetType();
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)
{
var myClassInstance = new 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
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
}
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)
{
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)
{
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.");
}
}
}
参考