Strange Linq Error - vb.net

I am using Linq to convert an array of any object to a CSV list:
String.Join(",", (From item In objectArray Select item.ToString()).ToArray())
This is giving me the strange error: "Range variable name cannot match the name of a member of the 'Object' class."
I can get round it by wrapping the string in a VB StrConv method, with a setting of "Nothing":
String.Join(",", (From item In oArray Select StrConv(item.ToString(), VbStrConv.None)).ToArray())
However, this seems like a bit of a hack and I would like to avoid it.
Does anyone have any ideas when this problems occurs, and any better ways to get round it?

Modify your code to:
String.Join(",", (From item In objectArray Select stringVal = item.ToString()).ToArray())
The problem is VB gives a name to the variable returned by Select clause. Implicitly, it tries to give the name ToString to item.ToString() which will clash with ToString method. To prevent so, you should explicitly specify a name (stringVal in above line).

Related

Why does this simple string formating now throw exception?

I'm using Authorize.net API and they require card expiration field to be formated as "yyyy-mm". We did that with this simple line of code:
expirationDate = model.Year.ToString("D4") & "-" & model.Month.ToString("D2")
and this absolutelly worked. I still have cards stored in the system that were saved using this method! But today I was testing something completelly unrelated, and wanted to add another card, and bam, this code exploded with this exception:
System.InvalidCastException: 'Conversion from string "D4" to type 'Integer' is not valid.'
Inner exception to that one is:
Input string was not in a correct format.
This just... doesn't make sense to me. Why in the world is it trying to convert format specifier (D4) into an integer? What input string? What in the world changed in two days?
The problem is that your are using a Nullable(Of Integer). This is a different structure that does not support the overloads of the ToString method a normal Integer has.
You can view the overloads of the Nullable structure here.
I suggest you use the GetValueOrDefault() method to get the proper Integer and also apply the value you expect in case the value is Nothing.
If it is impossible that a instance with a Nothing set for the year reaches this method you can simply use the Value property.
I still do not fully understand why you get this strange error message. Maybe you could check out what the actual method that is called is? Pointing at the method should give you that information. It can't be Nullable(Of Integer).ToString
Well, I found a workable solution and something of an answer thanks to #Nitram's comment. The type of Year/Month property has been changed from Integer to Integer?. Obviously, this isn't a very satisfying answer because I still don't understand why the nullable int can't be formatted, and yet the code compiles perfectly. The working solution for me has been using static format method on String as so:
expirationDate = String.Format("{0:D4}-{1:D2}", model.Year, model.Month)
This works fine even with nullable types.

How to get checked state of Checked Listbox vb.net

I have a checked listbox which I am running through and saving names to a database. As I run through I need to see if the check box is checked or clear.
I've tried the following code but to no avail:
If chklbRegister.GetItemCheckState(nLoop).ToString = "1" Then
.Parameters.AddWithValue("#sqlAttended", 1)
Else
.Parameters.AddWithValue("#sqlAttended", 0)
End If
I have also tried:
If chklbRegister.GetItemCheckState(nLoop) = True Then
but it still doesn't worked. Ideas please.
Thanks
Graham
GetItemCheckState returns an Enum. An enum is not a string and not a boolean.
You should test again the defined values of the enum
If chklbRegister.GetItemCheckState(nLoop) = CheckState.Checked Then
-----
If you apply the ToString method to an enum value you get the translated text of the enum, in your case the word "Checked" and not the string "1".
Of course, being the enums fundamentally numeric values of integral type you could always cast the return value to an integer, but you never should do it and use instead the proper Enum syntax
As a final note. This problem should have been signaled by the compiler and not slipped past the compilation phase. This compiler behavior is caused by the Option Strict set to Off instead of On. I suggest to change this option in the configuration of your project to avoid other errors of this kind that could be very subtle.
You can see for the documentation for GetItemCheckState that it returns a value from the CheckState enumeration so you need to check this:
chklbRegister.GetItemCheckState(nLoop) = CheckState.Checked

How get selected listitems using linq - lambda syntax?

I'm using VB.Net and I would like to know how to get the selected checkboxes in a checkboxlist using linq and lambda syntax (not query syntax, repeat NO query syntax).
I tried this but it's definitely not right.
cblRequired.Items.OfType(Of ListItem).Where(Function (i As ListItem ) i.Selected End Function)
I believe that the only thing wrong with your code is that you should not have the End Function, since it's a single-line lambda expression. This should work:
cblRequired.Items.OfType(Of ListItem).Where(Function(i As ListItem) i.Selected)
Technically, you don't need to specify the type of i, since it will automatically infer the type:
cblRequired.Items.OfType(Of ListItem).Where(Function(i) i.Selected)
If you want it to be a multi-line lamba expression, that would look like this:
cblRequired.Items.OfType(Of ListItem).Where(Function(i)
Return i.Selected
End Function)

Option Strict and Anonymous Types dont go together?

I have a Linq query that yields anonymous types. However, now I want to work with the parameters of this anonymous type and it does not seem to work.
For Each obj As Object in Query
Dim row As DataRow = obj.parameter
...
Next obj
Now the compiler throws an error on the expression obj.parameter: "Option Strict On disallows late binding". If I understand it right, the compiler doesnt know the parameters of the anonymous type. I tried Option Infer On (and removed As Object), based on Google results, but it didnt help. Which seems to make sense, because it always seems to be a widening conversion to me.
Is there anyway to fix this, or should I just create a custom type?
The code that declares the anonymous type (i.e. the Select part of your LINQ query) must be in the same method as the the code that uses it and the Query variable's declaration must have an inferred type. You cannot access the properties of an anonymous type after it has been cast to an Object since there is no named type to which you can cast it.
So make sure that your LINQ query (or, at least, the part that Selects into a new anonymous type) is in the same method. E.g.
Dim Query = From prod In products
Select prod.Name, prod.Price
For Each obj in Query
Dim name = obj.Name
...
Next obj

Write String.Join(Of T) in VB.Net

I have a simple code in C#:
Console.WriteLine(string.Join<char>("", ""));
And I can't convert it to VB.Net. Even reflector show me code in VB like:
Console.WriteLine(String.Join(Of Char)("", ""))
But it can't be compiled becouse I have an starge error:
Error 1 Expression expected.
It looks like VB.Net don't have this generic method at all.
Both project use Net Framework 4.
Why this error happened?
UPD:
I've create a custom class and copy Join(Of T) declaration to it:
Class string2
Public Shared Function Join(Of T)(ByVal separator As String, ByVal values As System.Collections.Generic.IEnumerable(Of T)) As String
Return "1"
End Function
End Class
Console.WriteLine(string2.Join(Of Char)("", ""))
It works
UPD2:
My compilation string, where you can see that I'm using Net4:
http://pastebin.com/TYgS3Ys3
Do you have a code element named String somewhere in your project?
Based on the answer you have added to this question (where you indicate that changing String to [String] appears to have solved the problem), I guessed that this may be the result of a naming collision.
I was able to duplicate the error you are seeing -- "Expression expected" -- by adding a module to my project called String and defining a (non-generic) Join method from within that module.
This may not be the specific scenario you find yourself in. But the fact that the code works for you with [String] is, to me, very compelling evidence of a simple namespace collision.
Based on the documentation for the "Expression expected" error, I'm guessing you haven't included the entire section of code where this error is appearing for you.
Do you have a lingering operator such as + or = somewhere?
(The VB.NET code you posted is indeed equivalent to the C# code above it and should compile no problem. This is why I suspect the real issue lies elsewhere.)
String.Join<T>(string, IEnumerable<T>) is useful with LINQ, for standard joins is better to use the String.Join(string, string()) overload.
In C#, "" as Char produces an empty Char (\0). Writing the same thing ("") in VB produces an empty string which is not the same as an empty char. In order to produce an empty character, you'll have to write New Char().
Your VB code therefore becomes:
Console.WriteLine(String.Join(Of Char)(New Char(), New Char()))
Edit
I just checked and it appears String.Join does not support the format you're specifying.
Instead, it goes as follows:
Join(separator As String, value As String()) As String
Your code should be as follows:
Console.WriteLine(String.Join("", New String() {""}))
String.Join(Of Char)(str1, str2) wasn't added til .net 4, it seems. That's why your custom class worked -- it had the declaration, but the String class in the framework you're actually using doesn't.
Check your settings and references to make sure you're targeting .net 4 all around -- cause that's the only thing that seems able at this point to stop the call from working.
Here the solution:
Console.WriteLine([String].Join(Of Char)("", ""))
Why this problem occurs only with generic method? I wish I know...