属性变更的记录在很多应用场景中有使用,如用做审计日志或操作日志记录等等。
记录属性值变化的方式有很多,但是有一个特性能帮助我们优雅的记录值变化,仅需一个公共方法,即可实现所有属性值变更记录;
CallerMemberNameAttribute 官方解释为:允许获取方法调用方的方法或属性名称,在
System.Runtime.CompilerServices 命名空间下;
下面来看如何使用此特性实现优雅的记录属性值变化。
class A
{
private int? age;
public int? Age
{
get { return age; }
set {
if(age.HasValue&&age.Value!=value) //初始值为null时不记录,可根据实际情况自定义
{
PropertyLog.Change(age,value); //在需要记录变更的属性中,加入此方法
}
age=value;
}
}
}
class PropertyLog
{
/*
CallerMemberName 标记的 propertyName 参数 必须有默认值
oV为旧值
nV为新值
*/
public static void Change<T>(T oV,T nT,[CallerMemberName] string propertyName="")
{
Console.WriteLine($"Property[{propertyName}] value from [{oV}] to [{nT}]");
}
}
class Program
{
static void Main(string[] args)
{
A a=new();
a.Age=17; //因属性set做了处理,初始值为null时不记录,此时不会输出
a.Age=18; //属性值变更触发日志,输出 Property[Age] value from [17] to [18]
}
}
CallerMemberNameAttribute 能获取到调用方的属性和方法名,无法获取属性中使用的特性,如使用 DescriptionAttribute 作为属性名称的描述,日志需要记录该属性的描述时无法通过此特性获取,可以考虑用反射的方式获取。
备注:CallerMemberNameAttribute 支持.NET Core的所有版本,在.NET Framework 中支持4.5及以上版本。