【问题标题】:How can I get a property name for a type without the need to instantiate an object of that type?如何在不需要实例化该类型的对象的情况下获取类型的属性名称?
【发布时间】:2012-05-23 07:48:17
【问题描述】:

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

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

现在,我知道您可以使用实例化对象来做到这一点,例如 ...

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

我的辅助方法使用反射将属性名称作为字符串获取 - 网络上有很多这样的例子!

但我不想创建这个毫无意义的对象,我只想做一些类似 MyObject.MyProperty 的事情!反射允许您在不声明该类型的对象的情况下迭代类型属性和方法...但我想访问特定属性并检索其名称的字符串版本,而无需迭代且不声明该类型的对象!

这里的要点是,虽然我试图将属性名称作为字符串获取……这是在运行时完成的……在编译时,我希望这是类型安全的,所以如果有人更改了属性名称,编译将中断。

谁能帮忙完成这个任务!?!

【问题讨论】:

  • 如果它只是使用字符串变量来存储属性名称,它会如何获得编译错误?实现这一点的唯一方法是自动生成一些代码,然后编译生成的代码。然后编译将失败。但是,如果您在运行时使用反射,则无法通过编译错误使其失败。
  • 只是想让代码类型安全。所以我想避免这样的调用: CallMethod(_myList, "MyProperty") .... 并进行如下调用: Callmethod(_myList, MyObject.MyProperty) .... 因此,即使其他开发人员更改,前者也会编译实际的属性名称...而后者会引发编译时错误。
  • 啊,好的。这现在更有意义了。这让我想起了。一些单元测试框架,如 NUnit 和 Moq,使用 lambda 表达式来做这种事情。请参阅下面的答案。

标签: vb.net reflection types properties


【解决方案1】:

所以这里有一个快速的代码清单来展示我正在寻找的答案:

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

【讨论】:

    【解决方案2】:

    您可以将属性作为简单的 lamdba 表达式传入,并在方法中将其作为表达式树。您应该能够分析表达式树以获取属性的字符串名称,但如果属性名称更改,lambda 表达式将无法编译。查看此页面了解更多详情:

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

    【讨论】:

    • 是的,找到了基于表达式的解决方案。下次我在我的电脑上时会发布它!感谢您的帮助伙伴。
    【解决方案3】:

    您可以使用 NameOf 函数:

    Dim fieldName = nameOf(MyClass.MyField)
    

    【讨论】:

      猜你喜欢
      • 2014-09-13
      • 1970-01-01
      • 2016-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多