我想创建一个自定义扩展名,该扩展名将对对象T
的属性起作用,而与属性的类型无关。我需要扩展名才能获取DefaultValue
属性的值。
看着下面的课程,我希望能够做这样的事情:
Employee employee = new Employee();
string defaultNationality = employee.employeeNationality.GetDefaultValue();
[Employee
定义为]
public class Employee
{
[Browsable(false)]
public int employeeKey { get; set; }
[DisplayName("Name")]
[Category("Design")]
[Description("The name of the employee.")]
public string employeeName { get; set; }
[DisplayName("Active")]
[Category("Settings")]
[Description("Indicates whether the employee is in active service.")]
[DefaultValue(true)]
public bool employeeIsActive { get; set; }
[DisplayName("Nationality")]
[Category("Settings")]
[Description("The nationality of the employee.")]
[DefaultValue("Dutch")]
public string employeeNationality { get; set; }
}
您可以使用这种扩展方法:
using System;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
public static class ObjectExtensions
{
public static K GetDefaultValue<T, K>(this T obj, Expression<Func<T, K>> exp)
{
var info = ((MemberExpression)exp.Body).Member;
return (K)(TypeDescriptor.GetProperties(info.DeclaringType)[info.Name]
.Attributes.OfType<DefaultValueAttribute>()
.FirstOrDefault()?.Value ?? default(K));
}
}
并像这样使用它:
var deualtValue = someObject.GetDefaultValue(x=>x.SomeProperty);
注
该方法尝试基于DefaultValue
属性获取属性的默认值,如果该属性没有此类属性,它将返回属性类型的默认值,例如整数属性,如果找不到DefaultValue
属性,则返回0。
为了获得属性和元数据,我通常使用TypeDescriptor
,因为它更灵活,但是使用Reflection也完全有效。
您需要使用GetCustomAttribute
方法来获取所需的属性值。例如,您可以将所需的扩展方法定义为
GetCustomAttribute
如果找不到所需的属性(在这种情况下为using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
public static class Extensions
{
public static T GetDefaultValue<S,T>(this S source,Expression<Func<S,T>> expression)
{
var body = expression.Body as MemberExpression;
if(body.Member.GetCustomAttributes<DefaultValueAttribute>().Any())
{
return (T)body.Member.GetCustomAttribute<DefaultValueAttribute>().Value;
}
return default;
}
}
),则可以返回该类型的默认值(或根据使用情况引发异常)。
用法如下:>
DefaultValueAttribute