VB.NET: Which As clause to use with anonymous type with Option Strict On? - vb.net

Consider the requirement to always declare Option Strict On. We'll always need to declare variables with the As keyword. What would be the type of an anonymous type?
Example : Dim product As ... = New With { Key .Name = "paperclips", .Price = 1.29 }
What will follow the As?

try either setting Option Infer On at the top of the class or a project level

Add an Option Infer On statement, then you don't use As. If you don't use Option Infer On, product will be of type Object (but you'd have to make Option Strict Off to compile). With type inference on, it will be type (compiler generated).

Related

Updating to use Option Strict On

I am working on updating a VB.net project to use Option Strict On throughout and seeing this error:
BC32013 Option Strict On disallows operands of type Object for operator '='. Use the 'Is' operator to test for object identity.
However when I try it the code does not work.
Code:
If (dtg_FieldSelector.Rows.Item(m_int_SelectedRow).Cells(0).Value = txt_FieldIndex.Text) Then
you need to stringify the datagrid value as it is Object and Strict on forbids the comparison of two different datatypes
If (dtg_FieldSelector.Rows.Item(m_int_SelectedRow).Cells(0).Value.ToString() = txt_FieldIndex.Text) Then

Using statement, As vs =

Is there a difference between using 'As' keyword and the '=' operator in vb.net?
Example:
Using aThing As New Thing()
...
End Using
' OR
Using aThing = New Thing()
...
End Using
There will be no effective difference if you have Option Infer On. If you have Option Infer Off then the first snippet will always result in a variable of type Thing while the second snippet will fail to compile with Option Strict On and result in a variable of type Object with Option Strict Off.
The first code snippet is explicit in its typing of the variable so it will be the type you specify regardless of what settings you have for Option Strict and Option Infer. The second code snippet is not explicit about the type so that type must be determined implicitly by the compiler. With Option Infer On, the type Thing can be inferred from the initialising statement. With Option Infer Off, the type will default to Object and late-binding must be used, which is not allowed with Option Strict On.
It's worth noting that your original question isn't really valid because it's actually not a case of using As or =. This:
Using aThing As New Thing()
is actually just a shorthand for this:
Using aThing As Thing = New Thing()
so you're actually using = either way and the choice is just whether or not to provide an As clause. An As clause is required with Option Strict On unless you also have Option Infer On and the type can be inferred from the initialising statement. If there is no initialising statement or the type of that statement is different to the type you want the variable to be then an As clause is required to tell the compiler the type of the variable that it cannot infer for itself.

Visual Studio suddenly wants me to declare loop iterators

I've been happily writing code like this:
For idtArticles = 0 To dtArticles.Rows.Count - 1
and this:
If request.QueryString.HasKeys() Then
For Each parameter In request.QueryString.AllKeys
requestVars.Add(parameter, request.QueryString(parameter))
Next
Else...
And suddenly it won't compile and giving errors
Error 34 'idtArticles' is not declared. It may be inaccessible due to
its protection level. ..userAccountModel.vb
Which assuming I can't go back to my lazy ways is fine to edit as
For idtArticles as Integer
But I don't know for exampple what the Request collection would be declared as..
Error 39 'Parameter' is a type and cannot be used as an
expression. ..userAccountModel.vb
How can I make it go back to not caring? Also if not, what shall I DIM that Parameter as?
I've checked and Option Strict is OFF. In Tools.. Default Project Settings.
Thanks!
From Microsoft Doc on Option Infer Statement:
When you set Option Infer to On, you can declare local variables
without explicitly stating a data type. The compiler infers the data
type of a variable from the type of its initialization expression.
I would try this at the top of your code file:
Option Infer On
Or, alternatively you can change this on My Project -> Compile - Option Infer, right under Option strict!

Why doesn't VB.Net type inference work in class fields?

If I were to type the following into a method body:
Dim myInt = 1
the Visual Studio IDE (and therefore, I am guessing, the compiler) infers the type of myInt to be Integer.
EDIT
Apparently using a literal was a bad choice here, since I've become embroiled in a lengthy debate that has nothing to do with the question. If you take issue with the fact that the expression 1 might be interpreted as an instance of different numeric types, pretend I had written:
Dim myInstance = New MyClass()
END EDIT
However, when I put a field declaration with the exact same code at the top of a class, the type of myList is not inferred:
Public Class Foo
Dim myInt = 1
End Class
On mouseover, it mentions the absence of an As clause, and says a type of Object has been assumed. I cannot pass myInt as an argument to a function or sub that expects an Integer argument, without explicitly adding an As clause or casting to Integer.
Is there a discrepancy between how the IDE and compiler deal with type inference? If, on the other hand, the compiler can't infer type in this situation either, why the discrepancy between method variables and class fields?
What you've found is that way on purpose. here is the MSDN expalanation.
Local type inference applies at procedure level. It cannot be used to
declare variables at module level (within a class, structure, module,
or interface but not within a procedure or block). If num2 in the
previous example were a field of a class instead of a local variable
in a procedure, the declaration would cause an error with Option
Strict on, and would classify num2 as an Object with Option Strict
off. Similarly, local type inference does not apply to procedure level
variables declared as Static.

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