2012-05-15 39 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 
相關問題