2010-05-29 84 views
1

我很确定这是可能的,但我想要做的是有一个通用的方法,我可以在一个对象中传递一个表达式,该表达式将告诉方法要使用哪个Property这是逻辑。通过属性访问使用.NET

任何人都可以让我开始这样的语法吗?

本质上讲,我想代码是这样的:

Dim firstNameMapper as IColumnMapper = new ColumnMapper(of Author)(Function(x) x.FirstName) 
Dim someAuthorObject as new Author() 

fistNameMapper.Map("Richard", someAuthorObject) 

现在映射对象会知道设置名字属性设置为“理查德”。

现在在这里使用函数将不起作用,我知道这一点...我只是想给出一个想法,我正在努力。

感谢您的帮助!

回答

2

您可以使用表达式树来实现此行为,但通过ColumnMapper稍微不同的函数会简单得多。而不是使用表达式读取的属性,你可以给它设置属性值的函数:

Dim firstNameMapper as IColumnMapper = _ 
    new ColumnMapper(of Author)(Sub(x, newValue) _ 
     x.FirstName = newValue _ 
    End Sub) 

我觉得这个语法是在Visual Studio 2010中新的(但我不是一个VB专家) 。无论如何,参数的类型应该是Action<Author, string>,您可以随时从ColumnMapper中随时调用它来设置属性。

使用表达式树,您必须构造表达式来设置属性并在运行时对其进行编译,所以我认为上述额外的几位代码是解决问题的更简单的方法。

+0

太棒了,thx Tomas!我会试试这个。 – Bitfiddler 2010-05-29 20:58:23

0

好的,所以我实现了一个类似的解决方案(我没有使用2010,所以我不能直接使用Tomas的解决方案),但尽管它编译,属性似乎并没有设置。所以这里是所有部分:

Module Module1 

Sub Main() 
    Dim inputSource() As String = {"Richard", "Dawkins"} 
    Dim firstNameMapper As New ColumnMapper(Of Author)(Function(obj, value) obj.FirstName = value, 0) 
    Dim lastNameMapper As New ColumnMapper(Of Author)(Function(obj, value) obj.LastName = value, 1) 

    Dim theAuthor As New Author 

    firstNameMapper.map(inputSource, theAuthor) 
    lastNameMapper.map(inputSource, theAuthor) 

    System.Console.WriteLine(theAuthor.FirstName + " " + theAuthor.LastName) 
    System.Console.ReadLine() 
End Sub 

End Module 

Public Class ColumnMapper(Of T As {Class}) 

    Dim _propertyMapper As Action(Of T, String) 
    Dim _columnIndex As Int32 

    Public Sub New(ByVal mapAction As Action(Of T, String), ByVal columnNumber As Int32) 
     _propertyMapper = mapAction 
     _columnIndex = columnNumber 
    End Sub 

    Public Sub map(ByVal sourceFields As String(), ByRef destinationObject As T) 
     _propertyMapper(destinationObject, sourceFields(_columnIndex)) 
    End Sub 
End Class 

Public Class Author 
    Private _firstName As String 
    Private _lastName As String 

    Public Property FirstName() As String 
     Get 
      Return _firstName 
     End Get 
     Set (ByVal value As String) 
      _firstName = value 
     End Set 
    End Property 

    Public Property LastName() As String 
     Get 
      Return _lastName 
     End Get 
     Set (ByVal value As String) 
      _lastName = value 
     End Set 
    End Property 
End Class 

任何想法为什么没有设置属性?

0

不确定为什么使用内联'函数'的解决方案不起作用。也许有人更熟悉vb.net的内部工作原理可以解释它,但是如果你按如下方式实现主模块,它就可以工作。感谢Tomas指引我走向正确的方向!

Module Module1 
    Sub Main() 
     Dim mapAction As Action(Of Author, String) 

     Dim inputSource() As String = {"Richard", "Dawkins"} 
     Dim firstNameMapper As New ColumnMapper(Of Author)(AddressOf setFirstName, 0) 
     Dim lastNameMapper As New ColumnMapper(Of Author)(AddressOf setLastName, 1) 

     Dim theAuthor As New Author 

     firstNameMapper.map(inputSource, theAuthor) 
     lastNameMapper.map(inputSource, theAuthor) 

     System.Console.WriteLine(theAuthor.FirstName + " " + theAuthor.LastName) 
     System.Console.ReadLine() 
    End Sub 

    Public Sub setFirstName(ByVal obj As Author, ByVal value As String) 
     obj.FirstName = value 
    End Sub 

    Public Sub setLastName(ByVal obj As Author, ByVal value As String) 
     obj.LastName = value 
    End Sub 

End Module