154

Is there a VB.NET equivalent to the C# var keyword?

I would like to use it to retrieve the result of a LINQ query.

Matthew Murdoch
  • 30,874
  • 30
  • 96
  • 127
Jack
  • 1,549
  • 2
  • 9
  • 3
  • 4
    IMHO: Although this is a duplicate question, the answers & comments below provide more detail about the use of `option infer` and `option strict`, than the previously asked question. I prefer **THIS** Q & A, to that original. – ToolmakerSteve Dec 09 '13 at 21:45

4 Answers4

153

Option Infer must be on in order for this to function properly. If so, then omitting the type in VB.NET (Visual Basic 9) will implicitly type the variable.

This is not the same as "Option Strict Off" in previous versions of VB.NET, as the variable is strongly-typed; it's just done so implicitly (like the C# var) keyword.

Dim foo = "foo"

foo is declared as a String.

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
Adam Robinson
  • 182,639
  • 35
  • 285
  • 343
45

You need Option Infer On and then just use the Dim keyword, thus:

Dim query = From x In y Where x.z = w Select x

Contrary to some of the other answers, you do not need Option Strict On.

If you're using the VS IDE you can just hover over the variable names, but to get the compile-time types of variables (GetType(variableName) does not compile - "Type '<variablename>' is not defined." - and VarType(variable) is actually just the VB version of variable.GetType() which returns the type of the instance stored in the variable at runtime) I used:

Function MyVarType(Of T)(ByRef Var As T) As Type
    Return GetType(T)
End Function

In detail:

  • without Dim:

    Explicit Off, gives Object

    Explicit On, error "Name '' is not declared."

  • with Dim:

    • Infer On, gives expected types
    • Infer Off:

      Strict On, error "Option Strict On requires all declarations to have an 'As' clasue."

      Strict Off, gives Object

As I mentioned in the comments, there are other reasons why Option Strict On allows Linq to perform more usefully. Specifically, you can't get Into Max(Anon.SomeString) to work with Option Strict Off, though there are a number of workarounds.

Mark Hurd
  • 10,665
  • 10
  • 68
  • 101
  • You can simply use `x.GetType()` in VB – I hadn’t tested my answer’s code, hence the mistake in my old answer. This actually yields the runtime type which can differ from what you get using `GetType(T)`, though. Finally, `Strict On` if course not required for this to work, but should be always on, anyway, and may prevent mistakes if the programmer has forgotten to specify `Infer On`. – Konrad Rudolph Mar 22 '10 at 07:56
  • I agree `Option Strict On` is good practice, but `x.GetType` doesn't provide the answer to the question asked here. I haven't tested it, but with `Infer Off` and `Strict Off` a simple `Dim query = From ...` example may work (although the guts of Linq queries may need some of the other effects of `Strict On` or `Infer On` to work correctly) and `query.GetType()` will return the anonymous type, not `Object`, which query will be declared to be. – Mark Hurd Mar 23 '10 at 03:57
  • Thanks for the correction; I've altered my answer to reflect this adjustment. The wording of the MSDN docs is awkward and seems to imply that `Strict` is required, but they don't actually say that. – Adam Robinson Mar 23 '10 at 16:56
  • Mark, it might be worth mentioning, in your **without Dim** section, that `Strict On` also forces/implies `Explicit On`. http://support.microsoft.com/kb/311329 So no one needs to worry about `Explicit`, if they are using `Strict On`. – ToolmakerSteve Dec 09 '13 at 21:58
  • @ToolmakerSteve I would mention it, except the Microsoft support article is currently wrong: `Explicit On` is the default, but you can override it and still have `Strict On`. Then you can still have undeclared `Object` variables, but `Dim` statements must have an `As` clause (unless `Infer On` is also in effect). Sample code: http://ideone.com/rnC1Xk (ideone itself doesn't have a recent enough VB.NET compiler -- just using it as a public notepad) – Mark Hurd Dec 10 '13 at 09:21
18

Simply use the conventional Dim keyword without a type.

Minimal working example:

Option Strict On ' Always a good idea
Option Infer On ' Required for type inference

Imports System

Module MainModule
    Sub Main()
        Dim i = 42
        Dim s = "Hello"
        Console.WriteLine("{0}, {1}", i.GetType(), s.GetType())
        ' Prints System.Int32, System.String '
    End Sub
End Module
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • 1
    Isn't this wrong? According to other answers, Only `Option Infer` is needed? (Option Strict solves a different issue.) – ToolmakerSteve Dec 09 '13 at 21:48
  • @ToolmakerSteve Right. In a preview version of Visual Studio (don’t remember which one) you needed both, AFAIR. – Konrad Rudolph Dec 09 '13 at 22:09
  • The `.GetType` result would be the same if you had `Infer Off` and `Strict Off`, but the `i` and `s` would actually be `Object`. – Mark Hurd Dec 10 '13 at 13:34
-1

Object worked for me in this example

C#

JToken projects = client.Search(ObjCode.PROJECT, new { groupID = userGroupID });
foreach( var j in projects["data"].Children()) {
        Debug.WriteLine("Name: {0}", j.Value<string>("name"));
}

VB

Dim projects As JToken = client.Search(ObjCode.PROJECT, New With { _
Key .groupID = userGroupID _
})

For Each j As Object In projects("data").Children()
       Debug.WriteLine("Name: {0}", j.Value(Of String)("name"))
Next
Beto
  • 9
  • 8
    The VB code is using late binding here. (You wouldn't have intellisense when you type `j.`.) This does _not_ correspond to the C# code. – Mark Hurd Feb 14 '12 at 03:55
  • So we are saying there is no direct equivalent in VB for the var keyword when using a loop variable in a for loop e.g. the j above? This is the exact scenario I want var because I have a collection coming back from LINQ using an anonymous type so how do I get the elements?! – Alan Macdonald Jul 03 '13 at 13:19
  • 2
    @AlanMacdonald Just use `For Each j In ...` the type will then be inferred. – Mark Hurd Aug 05 '13 at 17:46
  • 3
    -1 because the result is dynamic (late) binding. Therefore, this is not an answer to the poster's question. I recommend removing this answer (which will also remove the -1 charge). – ToolmakerSteve Dec 09 '13 at 21:50