2017-07-29 113 views
1

我想传递一个属性给一个函数,使函数知道属性的值和属性的名称。这样我就可以返回与属性名称匹配的错误。C#从参数传递/检索属性名称而不反射

目前,我有这样的代码:

var userNameField = personField.GetChildField(f => f.UserName, nameof(personField.Value.UserName)); 

多次重复,所以第二个参数是第一个参数的拉姆达内部属性的名称。

是否有可能此参数,以便自动化:

  1. 重复的代码消失了
  2. 属性的字符串名称是在编译时计算的,不是每一个电话
运行时间

我非常希望我的代码只是看起来像:

var userNameField = personField.GetChildField(f => f.UserName); 

我有使用反射使用Expression<Func...((MemberExpression) getPropertyFunc.Body).Member.Name;得到了这个工作,但是这太慢了,特别是将表达式编译成函数,我可以使用它来获取属性值。

同样,我已经通过这里的想法阅读:Get name of property as a string

是否有从在编译时GetChildField功能填充属性名称的方法吗?或者以某种方式将其编码到模型中?

+0

如果编译表达式是太慢了,你试图缓存在编译的结果呢?它不会让第一个呼叫更快,但随后的呼叫可能会受益。另外,由于您似乎只接受'x => x.Property'形式的表达式,您是否尝试通过反射而不是编译表达式来获取属性? –

+0

是否可以缓存编译结果?我调用了在整个代码库中用许多不同表达式编译表达式的方法,因此需要在每个调用的基础上进行缓存。你的第二点是正确的,但。我设法通过消除编译并通过反射获取属性来提高性能,但是它仍然不是理想的,因为属性名仍然是在运行时计算的(我相信..除非编译器做了一些有趣的事情)。 –

回答

-1

按照罗斯林文档发现herenameof操作者是在编译时每第一行中的“语义”单元,读取

的nameof表达是一个常数下评价。在所有情况下,nameof(...)都会在编译时进行评估以生成一个字符串。它的参数在运行时不被评估,并被认为是无法访问的代码(但它不会发出“无法访问的代码”警告)。

0

有可能通过以下几点:

Item model=new Item();  
var propertyInfo = model.GetType();  
var value=propertyInfo.GetProperty("IrrA").GetValue(model, null).ToString(); 
+0

OP没有要求没有反射解决方案吗? – kuskmen

+0

@kuskmen其实不,OP没有要求没有反思的解决方案。 OP仅声称编译表达式太慢。这可能比编译表达式更快(否则 - 我没有测试)。 –

+0

我问了一个解决方案,它在编译时计算属性名称,而不是运行时间。但是,该解决方案比编译表达式更快。 –