Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VB to C# conversion incongruency with lambdas

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?

like image 527
Jason Avatar asked Dec 04 '25 08:12

Jason


1 Answers

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

Option Strict On does not allow narrowing in implicit type conversions between the lambda expression and delegate 'System.Predicate(Of OrderForm)'

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:

Dim inv As Invoice = DirectCast(Invs.Find(Function(someInv As OrderForm) SubPONumber = DirectCast(thePO.SubPONumber, Invoice).SubInvoiceNumber), Invoice)

UPDATE

Here's the C# version from @Anthony Pegram's post:

Invoice inv = (Invoice)Invs.Find(someInv => thePO.SubPONumber == ((Invoice)someInv).SubInvoiceNumber);

Also, I recommend that you make some changes to your pattern if possible. GetForms() right now returns OrderForms but later you just assume that they're all Invoices. Hopefully you've got some logic to verify that. I'd recommend that GetForms() actually returns Invoices otherwise.

like image 68
Chris Haas Avatar answered Dec 06 '25 00:12

Chris Haas