0

I am trying to get a string of BranchCode from an array of UserBranches(). For a specific user the list is nothing, therefore is causing an exception:

System.ArgumentNullException: 'Value cannot be null.
Parameter name: source'

I am using an IIF statement, but obviously does not help:

Dim sMatchedBranches = IIf(Not IsNothing(oUser.UserBranches),
                           oUser.UserBranches.Select(Function(z) String.Format("{0} - BranchCode", z.BranchCode)), "")

I have also used oUser.UserBranches.Any, but still the same exception. Any ideas?

** To the duplicate recommendation, it's actually not since the question combines both the IIF and also an empty array with lambda expressions.

7
  • 1
    Use If() instead of IIf(). Commented Jun 2, 2018 at 15:43
  • 2
    "Any ideas?" - Yes, select the ""References Tab" after clicking the Project Menu->"Project Name" Properties. Then under "Imported namespaces", uncheck "Microsoft.VisualBasic". This will make it harder for you to use the functions (like IIf) meant to make VB6 programmers comfortable in VB.Net and instead use If or write a standard If-Then block. Commented Jun 2, 2018 at 15:45
  • What version of VB are you using? If it's VB 14 or later, there is also the question mark operator (see visualstudiomagazine.com/Blogs/Tool-Tracker/2015/05/…). Also, If() has a two-parameter version. And there's $"" (string interpolation). So this might work: Dim sMatchedBranches = If(oUser.UserBranches?.Select(Function(z) $"{z.BranchCode} - BranchCode"), "") Commented Jun 2, 2018 at 16:02
  • @rskar Nice answer. Please post it as answer and I will accept it. Commented Jun 2, 2018 at 16:10
  • 1
    @alwaysVBNET - glad that helped! I'll post a very detailed answer for the benefit of future viewers. Commented Jun 2, 2018 at 16:22

1 Answer 1

3

First, I would reiterate what @TnTinMn has said: Try to wean off Microsoft.VisualBasic. It's OK to pick-and-choose whatever's useful there - in which case be very thoughtful and intentional (e.g. even C#'ers like InputBox a lot! - What is the C# version of VB.net's InputDialog?). However, VB today has so many nicer and better ways of getting things done.

The major flaw of ye olde IIf() is that it is just some function, which means every parameter gets executed no matter the condition. That makes it barely useful, even in VB6/VBA, because you just can't avoid any run-time-error/exception that you know is going to happen per the condition. If() on the other hand is an actual operator, and it delivers exactly what everyone wants - a way to carefully prune what gets executed in an expression without having to write a specialized function.

So the easy answer is just to replace IIf() with If() and be pretty much done with it:

Dim sMatchedBranches = If(Not IsNothing(oUser.UserBranches),
                       oUser.UserBranches.Select(Function(z) String.Format("{0} - BranchCode", z.BranchCode)), "")

And one might feel that's good enough. But there's three other tricks in VB to make things nicer yet.

The first is the ? operator. This is a handy way to say something like If(oUser.UserBranches Is Nothing, Nothing, oUser.UserBranches.Select(Function(z) String.Format("{0} - BranchCode", z.BranchCode))), except with ? it's now like this:

oUser.UserBranches?.Select(Function(z) String.Format("{0} - BranchCode", z.BranchCode))

The second trick is string interpolation, in the format of $"{myVar}". Instead of String.Format("{0} - BranchCode", z.BranchCode), it can now be:

$"{z.BranchCode} - BranchCode"

The third trick is about If(): If you give it two parameters, it will give a very handy way of dealing with Nothing. If(x,y) means if x is not Nothing, return x, otherwise return y. (If(x,y) means the same as x ?? y in C#.)

Putting it all together:

Dim sMatchedBranches = If(oUser.UserBranches?.Select(Function(z) $"{z.BranchCode} - BranchCode"), "")
Sign up to request clarification or add additional context in comments.

6 Comments

My goal was to get the branch codes as a string. By checking again now the code I get an error. Any ideas? Dim sMatchedBranches As String = If(oUser.UserBranches?.Select(Function(z) $"{z.BranchCode} - BranchCode"), "")
Ok, I did this: Dim sMatchedBranches As String = String.Join(",", oUser.UserBranches?.Select(Function(z) $"{z.BranchCode} - BranchCode")) which works
So, the goal is a comma-separated list of items? String.Join is fine for that, so what you have looks OK to me. But you probably still need to use If(x,y) in case oUser.UserBranches is Nothing.
Try this (warning, I'm flying blind here): Dim sMatchedBranches = String.Join(",", If(oUser.UserBranches?.Select(Function(z) $"{z.BranchCode} - BranchCode"), {""})) I'm hoping to nudge String.Join towards where its second parameter is something IEnumerable.
Cool! I hope this is the real answer for you.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.