我有一个具有属性的类,并且该属性具有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,并且很容易意外地传递错误的字符串。
如何改进此代码以删除重复?
答案 0 :(得分:3)
您没有说明您使用的是哪个版本的框架,但如果它是.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();
在运行时,系统会自动为您提供name
GetProperty
参数的值。
实际上,如果你这么做(并且它总是相同的属性),你可以更加简化:
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;
}
}
答案 1 :(得分:2)
使用MethodBase.GetCurrentMethod()
从方法或属性获取当前引用。在您的情况下,使用Name
属性,该属性将返回字符串get_MyProperty
,并使用get_
删除substring
部分,请尝试以下操作:
[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;
}
}
答案 2 :(得分:1)
您可以使用这样的扩展方法:
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);
更好,并且使用编译时检查,它也适用于重构:)
扩展方法非常简单,你希望它更安全,但这个想法应该是明确的。