Adm*_*vić 3 c# generics reflection types
我正在为属性构建自己的库,我想检查属性级别是否有属性.目前我有这种方法可以正常工作:
public static bool HasPropertyAttribute<T>(this object instance, string propertyName)
{
return Attribute.GetCustomAttributes(instance.GetType().GetProperty(propertyName), typeof(T), true).Any();
}
Run Code Online (Sandbox Code Playgroud)
现在我正在研究解决方案,它允许我传递lambda表达式而不是string作为propertyName.是否有一种优雅的方法来做到这一点,而不添加此方法成为两个通用类型依赖,aka:
HasPropertyAttribute<T, TProperty>(...).
Run Code Online (Sandbox Code Playgroud)
您可以使用Lambda表达式来解析编译时属性引用.(从lambda表达式中检索属性名称修改的代码)
public PropertyInfo GetPropertyInfo<TProperty>(
Expression<Func<TProperty>> propertyLambda)
{
MemberExpression member = propertyLambda.Body as MemberExpression;
if (member == null)
throw new ArgumentException(string.Format(
"Expression '{0}' refers to a method, not a property.",
propertyLambda.ToString()));
PropertyInfo propInfo = member.Member as PropertyInfo;
if (propInfo == null)
throw new ArgumentException(string.Format(
"Expression '{0}' refers to a field, not a property.",
propertyLambda.ToString()));
return propInfo;
}
Run Code Online (Sandbox Code Playgroud)
你并不需要使用它作为一个扩展方法(但如果你要适应它,你可以,但有一个源对象实例是没有必要的,除了写行)
public class Test
{
public string Prop { get; set; }
}
Test t = new Test();
PropertyInfo propInfo = GetPropertyInfo(() => t.Prop);
Console.WriteLine(propInfo.Name + " -> " + propInfo.PropertyType); //Prop -> System.String
Run Code Online (Sandbox Code Playgroud)
编辑:如果你想要一些很好的语法,并且必须避免对该类型的对象进行现有引用,你可以执行以下操作:
public static class TypedReflection<TSource>
{
public static PropertyInfo GetPropertyInfo<TProperty>(
Expression<Func<TSource, TProperty>> propertyLambda)
{
MemberExpression member = propertyLambda.Body as MemberExpression;
if (member == null)
throw new ArgumentException(string.Format(
"Expression '{0}' refers to a method, not a property.",
propertyLambda.ToString()));
PropertyInfo propInfo = member.Member as PropertyInfo;
if (propInfo == null)
throw new ArgumentException(string.Format(
"Expression '{0}' refers to a field, not a property.",
propertyLambda.ToString()));
return propInfo;
}
}
Run Code Online (Sandbox Code Playgroud)
称之为:
PropertyInfo propInfo = TypedReflection<Test>.GetPropertyInfo(o => o.Prop);
Run Code Online (Sandbox Code Playgroud)
此时,添加其他类型反射方法(获取方法,字段等)非常容易.
编辑:它仍然是两种依赖的泛型类型,但它通过类型推断隐藏起来.我更喜欢第二个例子; 至少你需要指定声明类类型(因为你想要类型安全),但是你不需要一个对象实例.它还有一个好处(我怀疑你后),如果您重命名的属性,它的传播到此代码获得PropertyInfo.