2012-05-15 40 views
1

我有一个需求,我需要有一个“类型安全”的方式来访问属性名称,而不需要实际实例化一个对象来获取属性。举个例子,考虑一个方法,该方法需要一个IMyObject列表和一个表示属性名称(IMyObject中存在的属性)的字符串作为参数。如何获取某个类型的属性名称而不需要实例化该类型的对象?

该方法的实现将采取列表并访问列表中的所有对象使用传递的属性名称......出于某种原因或另一个,我们不会详谈!

现在,我知道,你可以使用一个实例化的对象,像这样做...

Dim x as MyObject = nothing 
Dim prop As PropertyInfo = PropHelper.GetProperty(Of MyObject)(Function() x.MyProperty) 

凡我helper方法使用反射来获取属性作为字符串的名称 - 有无数这个在网上飞行的例子!

但我不想创建这个毫无意义的对象,我只是想做一些像MyObject.MyProperty! Reflection允许你遍历一个类型的属性和方法,而不需要声明该类型的对象......但是我想访问一个特定的属性并且不需要迭代就可以获取它的名字的字符串版本,也不需要声明这种类型的对象!

这里的主要观点是,尽管我试图将属性名称作为字符串......这是在运行时完成的...在编译时,我希望这是类型安全的,所以如果有人更改属性名称,编译将会中断。

任何人都可以在这个任务帮助!?!

+1

它怎么会得到,如果一个编译错误只是使用一个字符串变量来存储属性名称?唯一的方法是自动化一些代码生成,然后编译生成的代码。那编译就会失败。但是,如果您在运行时使用反射,则无法通过编译错误使其失败。 –

+0

只是想让代码类型安全。所以我想避免像CallMethod(_myList,“MyProperty”)这样的调用....并且调用类似于:Callmethod(_myList,MyObject.MyProperty)....因此,即使其他开发人员更改,前者也会编译实际的属性名称......而后者会引发编译时错误。 –

+0

啊,好的。这现在更有意义。这提醒了我。一些像NUnit和Moq这样的单元测试框架用lambda表达式来做这种事情。请参阅下面的答案。 –

回答

0

您可以将该属性作为简单的lamdba表达式传递,并将其作为表达式树使用。您应该能够分析表达式树来获取属性的字符串名称,但是如果属性名称更改,lambda表达式将无法编译。看看这个页面了解详情:

http://msdn.microsoft.com/en-us/library/bb397951.aspx

+0

是的,找到了基于表达式的解决方案。我会在下次我在我的电脑上发布它!感谢您的帮助伴侣。 –

5

因此,这里是一个快速的代码清单,以证明我一直在寻找的答案:

Imports System.Linq.Expressions 

Public Class A 
    Public Prop1 As String 
    Public Prop2 As Integer 
End Class 

Public Class Form1 
    Public Function GetPropertyNameB(Of TModel, TProperty)(ByVal [property] As Expression(Of Func(Of TModel, TProperty))) As String 
     Dim memberExpression As MemberExpression = DirectCast([property].Body, MemberExpression) 
     Return memberExpression.Member.Name 
    End Function 

    Public Sub New() 
     InitializeComponent() 
     Dim propertyName As String = GetPropertyNameB(Function(myObj As A) myObj.Prop1) 
     Dim propertyName2 As String = GetPropertyNameB(Function(myObj As A) myObj.Prop2) 
     MsgBox(propertyName & " | " & propertyName2) 
     End 
    End Sub 
End Class 
相关问题