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.
Related
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
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.
Wrapping the argument in CObj or DirectCast shuts the compiler up, but the value is still not written.
Option Strict On
Imports System.Threading
Module Module1
Dim str As String
Sub Main()
Thread.VolatileWrite(str, "HELLO") ' Compiler error.
Thread.VolatileWrite(CObj(str), "HELLO") ' Fails silently.
Thread.VolatileWrite(DirectCast(str), "HELLO") ' Fails silently.
Console.WriteLine(str)
End Sub
End Module
There is no overload of Thread.VolatileWrite which takes a String argument. The only reference type supported is Object.
Because VolatileWrite is updating the variable str and Option Strict is On the compiler complains because in theory VolatileWrite could attempt to write a value to that variable which is not of type String (the compiler only sees that it might write any Object). In fact, as the VolatileWrite method also only takes a String you could write code which would attempt to do this. It would fail for reasons beyond the scope of this question.
When you wrap the expression in a COjb/CType/DirectCast expression (really anything with parenthesis) then the variable is no longer considered a variable but a value - it's treated the same way as if you'd just type a string literal there. Since values don't have storage locations the ByRefness of VolatileWrite is ignored which means it no longer writes which means it can no longer write a bad value which means the compiler doesn't need to warn anymore.
To get the behavior you want with a string type variable use the System.Threading.Thread.MemoryBarrier method before your writes and after your reads. See this thread for additional information: How do I specify the equivalent of volatile in VB.net?
So I have this:
Dim aBoolean As Boolean = True
Will it make any difference to just do this?
Dim aBoolean = True
In other languages, I believe it was a good practice to also define the type of variable it would be, for performance or something. I am not entirely sure with VB.NET.
Thanks.
It depends. Explicitly defining the variable can improve readability, but I don't think it's always necessary. (To be clear, it has nothing to do with the actual functionality of your code).
In this specific example, you follow the declaration with a Boolean assignment of True, so it's already crystal clear that aBoolean is actually a Boolean when it is declared. The As Boolean syntax is not as necessary in this scenario.
Other cases may not be so clear. If the declaration was followed by the result of a function call, for example, it might be more clear to explicitly declare that the variable is a Boolean. e.g.
Dim aBoolean As Boolean = TestValidityOfObject(o)
As long as you have Option Infer turned on, it won't make a bit of difference. The second line is just a syntactic abbreviation for the first. At that point, it's up to your style preference as to which you should use.
Before type inference, there were performance issues when not declaring the type, but that's no longer an issue; due to type inference the variable will be of type Boolean whether you declare it or not.
Declaring the type can help the compiler catch errors sooner, and will often give you better Intellisense.
You're using what's called "type inference". This is where the compiler figures out at compile time what the type on the right side of the assignment is and uses that as the type of the variable.
This is, in general, a safe and convenient feature. However, there are a couple of things to keep in mind:
You must have Option Infer on; otherwise, the compiler doesn't do type inference and, depending on your setting for Option Strict, instead either gives you a compile time error (Option Strict On) or types your variable as Object and uses late binding everywhere. This is Pure Evil. (Option Strict Off)
In your particular case, there's no way for the compiler to mess up. HOWEVER, it's possible to use type inference in such a way as to change the semantics of your code:
For instance...
Dim myClass as MyBaseClass = New SubClass()
This is perfectly legal; we're typing the variable as a base class and assigning a value to it that represents an instance of a subclass. Nothing special. However, if we switch to type inference by just removing the type declaration...
Dim myClass = New SubClass()
Type inference will now see myClass as a SubClass instead of MyBaseClass. This might seem obvious, but the point is that you should be aware of what it's doing.
For more information and long-winded discussion about using type inference, see this question. While that question is targeted at C#, the only real difference is the first item that I listed above. Everything else is conceptually the same.
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).