jhi*_*man 6 c# reflection types properties
我有一个数据库对象类,做了一堆繁重的工作.然后,我扩展该对象并构建表示要修改的实际对象和字段的类.它基本上看起来像这样:
public class MyObject : DatabaseObject
{
public string FieldX
{
get { return GetValue<string>("FieldX"); }
set { SetValue<string>("FieldX", value); }
}
public int FieldY
{
get { return GetValue<int>("FieldY"); }
set { SetValue<int>("FieldY", value); }
}
}
public class DatabaseObject
{
public T GetValue<T>(string FieldName)
{
// Code that actually gets the right value
}
public void SetValue<T>(string FieldName, T value)
{
// Code that actually sets the value in the right place
}
}
Run Code Online (Sandbox Code Playgroud)
这样,我以后可以实例化MyObject并开始通过代码设置属性.我们的想法是生成更简单,更易于维护的代码.
它在实践中很有效.但是,我注意到MyObject的代码非常重复.例如,使用FieldX,我最终在get/set中指定了"string"类型,并且还必须在get/set中指定属性名称"FieldX".
我想知道是否有办法进一步简化代码以减少重复.
我知道我可以使用反射:
MethodBase.GetCurrentMethod().Name.Substring(4)
Run Code Online (Sandbox Code Playgroud)
...在get/set调用中获取属性名称,我可以使用GetType()来获取set时的值类型,但理想情况下我想从基本GetValue /中获取原始属性名称SetValue方法(理想情况下不解析堆栈跟踪).
理想情况下,我正在寻找这样的东西:
public string FieldX
{
get { return GetValue(); }
set { SetValue(value); }
}
public int FieldY
{
get { return GetValue(); }
set { SetValue(value); }
}
Run Code Online (Sandbox Code Playgroud)
有什么想法吗?
C#5.0通过[CallerMemberName]在默认参数上使用属性来支持此功能.像这样的东西:
public static object GetValue([CallerMemberName] string caller = "")
{
Trace.WriteLine("Called by: " + caller);
return null;
}
Run Code Online (Sandbox Code Playgroud)
并将使用如下:
public string FieldX
{
get { return (string)GetValue(); }
}
Run Code Online (Sandbox Code Playgroud)
这适用于编译器GetValue根据调用者的名称自动提供参数.
您可以在MSDN中了解有关此功能的更多信息.
你可以制作GetValue通用的,这样它就可以像GetValue<string>()你的属性一样使用.
这比您想要的要长一些,但也可以使用(使用强类型lambda 表达式)。
public class MyObject : DatabaseObject
{
public string FieldX
{
get { return GetValue(() => FieldX); }
set { SetValue(() => FieldX, value); }
}
public int FieldY
{
get { return GetValue(() => FieldY); }
set { SetValue(() => FieldY, value); }
}
}
public class DatabaseObject
{
public T GetValue<T>(Expression<Func<T>> field)
{
string fieldName = GetFieldName(field);
// Code that actually gets the right value
}
public void SetValue<T>(Expression<Func<T>> field, T value)
{
string fieldName = GetFieldName(field);
// Code that actually sets the value in the right place
}
private static string GetFieldName<T>(Expression<Func<T>> field)
{
return ((MemberExpression)field.Body).Member.Name;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
852 次 |
| 最近记录: |