我想创建一个函数,它接受一个对象列表,循环遍历它们并将customername附加到每个对象。目标是调用此方法的用户将告诉对象中的哪个属性包含customernumber,以及用于设置从db获取的customername的属性。
现在我已经完成了很多逻辑,但是我正在努力使它尽可能强大地输入。所以我想我可以使用Linq表达式作为参数。这就是我现在所拥有的:
Public Shared Sub FillCustomerNames(Of TModel As Class)(objects As IEnumerable(Of TModel),
customerNumberExpression As Func(Of TModel, Integer),
customerNameExpression As Func(Of TModel, String))
Dim customerNumbers As List(Of Integer) = objects.Select(customerNumberExpression).Distinct().ToList()
' Fetch names from the database...
Dim customerNames = From c In Customers...
' Combine original objects with names
Dim joinResult = From original In objects
Let customerNumber As Integer = customerNumberExpression.Invoke(original)
Join customer In customerNames On customerNumber Equals customer.CustomerNumber
Select original, customer.CustomerName
For Each item In joinResult
' How to set the property in the expression?
' item.original.(property wanted) = item.customerName
Next
End Sub
我希望能够用这样的东西来称呼它:
FillCustomerNames(Of ADDRESS)(addresses,
Function(a) a.CustomerNumber,
Function(a) a.CustomerName)
现在Customernumber表达式(我用来从对象获取customernumber)工作正常。但你怎么做那个二传手呢?我想我不能用这种表达方式做到这一点?我需要一个动作吗?什么是最简单的方法。
我知道我可以使用反射并将属性名称作为字符串传递,但它不是强类型的,因为它会是。
任何帮助表示赞赏!
答案 0 :(得分:1)
但你怎么做那个二传手呢?我想我不能用这种表达方式做到这一点?我需要一个动作吗?
是。我正在从C#(在我的脑海中)翻译成你的VB.NET,所以如果我的语法错误就道歉。
您已经知道如何将 getter 传递给您的方法 - 作为Func(Of T, Integer)
,需要T
和返回 Integer
。您现在想要的是将 setter 传递给您的方法。一个setter(在这种情况下)是一个需要T
和String
并且......做某事,然后返回 nothing 的东西。为此,您可以使用Action(Of T, String)
,如下所示:
您的方法签名变为
Public Shared Sub FillCustomerNames(Of TModel As Class)(
objects As IEnumerable(Of TModel),
customerNumberGetter As Func(Of TModel, Integer),
customerNameSetter As Action(Of TModel, String))
(注意我已从参数名称中删除Expression
,因为这可能与Linq Expression功能混淆,后者未在此处使用)
而且:
For Each item In joinResult
' How to set the property in the expression?
' item.original.(property wanted) = item.customerName
Next
变得简单
For Each item In joinResult
customerNameSetter(item.original, item.customerName)
Next
请记住,customerNameSetter
是一个Action
,因此可以简单地调用,就像它是一个“真正的”方法一样。
通话网站将成为:
FillCustomerNames(Of ADDRESS)(addresses,
Function(a) a.CustomerNumber,
Sub(a, name) a.CustomerName = name)
(这是我不完全确定用于声明lambda Sub
的VB.NET语法的地方)