VB 到 C# 的转换与 lambda 不一致
我有一些代码,我的任务是将 VB 转换为 C#。我的一个片段似乎无法从一个转换为另一个,如果是这样,我只是不知道该怎么做,并且感到有点沮丧。
以下是一些背景知识:
OrderForm
是一个 abstract
类,由 Invoice
(以及 PurchaseOrder
)继承。以下 VB 代码片段可以正常工作:
Dim Invs As List(Of OrderForm) = GetForms(theOrder.OrderID)
....
Dim inv As Invoice = Invs.Find(
Function(someInv As Invoice) thePO.SubPONumber = someInv.SubInvoiceNumber)
在 C# 中,我转换此内容的最佳方式是:
List<OrderForm> Invs = GetForms(theOrder.OrderID);
....
Invoice inv = Invs.Find(
(Invoice someInv) => thePO.SubPONumber == someInv.SubInvoiceNumber);
但是,当我执行此操作时,出现以下错误:
无法将 lambda 表达式转换为委托类型“System.Predicate”,因为参数类型与委托参数类型不匹配
有没有办法在不重构整个代码库的情况下解决此问题?
I have a bit of code that I have been tasked with converting to C# from VB. A snippet of mine seems like it cannot be converted from one to the other, and if so, I just don't know how to do it and am getting a little frustrated.
Here's some background:
OrderForm
is an abstract
class, inherited by Invoice
(and also PurchaseOrder
). The following VB snippet works correctly:
Dim Invs As List(Of OrderForm) = GetForms(theOrder.OrderID)
....
Dim inv As Invoice = Invs.Find(
Function(someInv As Invoice) thePO.SubPONumber = someInv.SubInvoiceNumber)
In C#, the best I came to converting this is:
List<OrderForm> Invs = GetForms(theOrder.OrderID);
....
Invoice inv = Invs.Find(
(Invoice someInv) => thePO.SubPONumber == someInv.SubInvoiceNumber);
However, I get the following error when I do this:
Cannot convert lambda expression to delegate type 'System.Predicate' because the parameter types do not match the delegate parameter types
Is there any way to fix this without restructuring my whole codebase?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
每当您将 VB 转换为 C# 时,始终打开 OPTION STRICT ON。在这种情况下,您甚至在点击 c# 之前就会看到错误消息。在这种情况下VB将返回
从那里您可以很容易地看到您正在尝试将基类隐式转换为子类。人们在这里编写的 C# 代码是正确的,这里是 VB 等效代码:
更新
这是 @Anthony Pegram 帖子中的 C# 版本:
另外,如果可能的话,我建议您对模式进行一些更改。
GetForms()
现在返回OrderForms
,但稍后您就假设它们都是Invoices
。希望你有一些逻辑来验证这一点。我建议GetForms()
实际上返回Invoices
否则。Whenever you convert VB to C#, ALWAYS TURN OPTION STRICT ON. In this case you'll see the error message before you even hit c#. In this case VB will return
From there you can pretty easily see that you're trying to implicitly cast a base class as a child class. The C# code that people wrote here is correct, here's the VB equivalent:
UPDATE
Here's the C# version from @Anthony Pegram's post:
Also, I recommend that you make some changes to your pattern if possible.
GetForms()
right now returnsOrderForms
but later you just assume that they're allInvoices
. Hopefully you've got some logic to verify that. I'd recommend thatGetForms()
actually returnsInvoices
otherwise.好吧,
Find
需要一个Predicate
,但您试图给它一个Predicate
。这是正确的,这不应该编译。我对 VB.NET 的工作原理感到惊讶。什么是
thePO
?此外,
Find
的结果是一个OrderForm
,并且您正在分配给Invoice
类型的变量。理想情况下,您想要这样的东西:
如果您想提取发票,您可以这样做:
但实际上,如果您在
Invoice
之后,为什么要将列表键入为List< ;OrderForm>
而不是List
?Well,
Find
is expecting aPredicate<OrderForm>
but you are trying to give it aPredicate<Invoice>
. It is correct that this should not compile. I'm surprised the VB.NET works.What is
thePO
?Additionally, the result of
Find
is anOrderForm
and you are assigning to a variable of typeInvoice
.Ideally, you want something like this:
If you want to pull invoices, you could do something like this:
But really, if you are after
Invoice
s, why are you typing the list asList<OrderForm>
instead ofList<Invoice>
?我猜测
OrderForm
源自Invoice
。如果是这样,请重写您的 lambda 以省略Find
内的显式类型声明。 (对于 VB 不能肯定地说,但对于 C#,lambda 中不需要类型,它将被推断出来。)编辑
根据您的评论,您将不得不这样做lambda 内部的一些转换以及结果。
或者,您可以选择使用 LINQ 扩展方法,而不是在
List
中查找Find
I'm guessing that
OrderForm
derives fromInvoice
. If so, rewrite your lambda to omit the explicit type declaration inside theFind
. (Can't say with certainty for VB, but for C#, the type is not required in a lambda, it will be inferred.)Edit
Based on your comment, you're going to have to do some casting inside the lambda and also to the result.
Or you could elect to use LINQ extension methods as opposed to
Find
inList<>
编辑:
实际上,您不需要创建新列表
Edit:
Actually, you don't need to create a new list
我的猜测是,您需要将
OrderForm
转换为Invoice
:My guess is that you need to cast your
OrderForm
to anInvoice
: