[英]Can I get PropertyInfo for a field or property in a class without using reflection?
[英]Can I get PropertyInfo of a property without using its name?
我有一个具有属性的类,并且该属性具有一个attribute
,并且在该attribute
的get{}
或set{}
中,我想访问该属性。
有没有办法做到这一点而不必将属性的名称作为string
引用? 这行得通吗?
class MyClass
{
[DefaultValue("This is my default")]
public string MyProperty
{
get
{
string value = this.db.getMyProperty();
if (value == null)
{
var myPropertyInfo = this.GetType().GetProperty("MyProperty");
var myAttributeInfo = myPropertyInfo.GetCustomAttribute(
typeof (DefaultValueAttribute)) as DefaultValueAttribute;
if (myAttributeInfo != null)
value = myAttributeInfo.defaultValue;
}
return value;
}
}
}
让我担心的是,传递属性名称违反了 DRY,并且很容易意外传递错误的字符串。
如何改进此代码以消除重复?
您没有说明您使用的是哪个版本的 Framework,但如果它是 .NET 4.5 或更高版本,您可以使用CallerMemberName
。 将以下方法添加到MyClass
:
private PropertyInfo GetProperty([CallerMemberName] string name = "")
{
var myPropertyInfo = this.GetType().GetProperty(name);
return myPropertyInfo;
}
然后,在MyProperty
更改
var myPropertyInfo = this.GetType().GetProperty("MyProperty");
到
var myPropertyInfo = this.GetProperty();
在运行时,将自动为您提供GetProperty
name
参数的值。
实际上,如果你经常这样做(并且它总是相同的属性),你可以进一步简化它:
private string GetDefaultValueForProperty([CallerMemberName] string name = "")
{
string defaultValue = null;
var myPropertyInfo = this.GetType().GetProperty(name);
var myAttributeInfo = myPropertyInfo.GetCustomAttribute<DefaultValueAttribute>();
if (myAttributeInfo != null)
{
defaultValue = (string)myAttributeInfo.Value;
}
return defaultValue;
}
然后你的属性中的代码如下所示:
[DefaultValue("This is my default")]
public string MyProperty
{
get
{
string value = this.db.getMyProperty();
if (value == null)
{
value = GetDefaultValueForProperty();
}
return value;
}
}
使用MethodBase.GetCurrentMethod()
从方法或属性获取当前引用。 在您的情况下,使用Name
属性,它将返回一个字符串get_MyProperty
并删除带有substring
的get_
部分,试试这个:
[DefaultValue("This is my default")]
public string MyProperty
{
get
{
string value = this.db.getMyProperty();
if (value == null)
{
// get property name from GetCurrentMethod.
// use the SubString to remove the "get_" that comes from .net internals
var propertyName = MethodBase.GetCurrentMethod().Name.Substring(4);
// keep your method
var myPropertyInfo = this.GetType().GetProperty(propertyName);
var myAttributeInfo = myPropertyInfo.GetCustomAttribute(
typeof (DefaultValueAttribute)) as DefaultValueAttribute;
if (myAttributeInfo != null)
value = myAttributeInfo.defaultValue;
}
return value;
}
}
您可以使用这样的扩展方法:
public static TValue GetDefaultValue<TParent, TValue>
(this TParent @this, Expression<Func<TParent, TValue>> e)
{
var member = (e.Body as MemberExpression).Member;
var attr = member.GetCustomAttribute(typeof (DefaultValueAttribute))
as DefaultValueAttribute;
return (TValue)attr.Value;
}
现在你只需要在你的财产中做到这一点:
return GetDefaultValue(i => i.MyProperty);
更好,并带有编译时检查,它也适用于重构 :)
扩展方法真的很简单,你希望它更安全,但想法应该很清楚。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.