VB.NET equivalent for C# 'dynamic' with Option Strict On

59,942

Solution 1

The equivalent is Object in VB.NET but with Option Strict Off. With Option Strict On there's no equivalent. Put another way the dynamic keyword brings Option Strict Off equivalent functionality to C#.

Solution 2

VB.NET always had the "dynamic" feature built in, originally called late binding. This syntax was supported forever:

 Dim obj = new SomeComClass()
 obj.DoSomething()

Worked on code implemented in .NET and COM, the latter being the most common use. The dynamic keyword in C# gave it that same capability. It did get changed in VB.NET version 10 however, it is now using the DLR as well. Which adds support for dynamic binding to language implementations like Python and Ruby.

The syntax is exactly the same, use the Dim keyword without As. You will however have to use Option Strict Off, Option Infer On can soften that blow a bit. It does show that C# using a specific keyword to signal dynamic binding was a pretty good move. Afaik all requests to do so in VB.NET as well have as yet been considered but not planned.

If you prefer Option Strict On, then using the Partial Class keyword so you can move some of the code into another source file is probably the most effective approach.

Solution 3

This will demonstrate what Basic is saying about VB not having the same granularity in this as C#. I have this piece of code in C#, that uses reflection to dynamically invoke a method at runtime:

var listResult = tgtObj.GetType().GetMethod("GetSomeData").Invoke(tgtObj, null);

The reason I'm doing this is that "GetSomeData" could be any of a number of methods, each getting different data. Which method to invoke here is dependent on a string parameter passed into this object at runtime, so, value of "GetSomeData" varies at runtime.

The signature of "GetSomeData" is:

public List<SomeResultSetClass> GetSomeData()

Each one of the methods invoked returns some sort of List<T> object. Next, I'm sending the listResult object to a generic method called Export, which looks like this:

void Export<T>(List<T> exportList, string filePath, byte fileType) where T: class;

Here's where we run into a problem. Invoke returns an object of type System.Object. Of course, a List<T> is also a System.Object, but the interface exposed is the System.Object interface, not the IList interface. If I try to execute the Export method, thus:

myExportObj.Export(listResult, parms.filePath, parms.fileType);

the code fails to compile. The error is:

The type arguments for method '...Export<T>...' cannot be inferred from the usage. Try specifying the type arguments explicitly.

No thanks!! The problem is that the compiler can't find the IList metadata, because it's looking at the System.Object interface. Now, you can create a new List<T>, assign (List<Whatever>) listResult to it, but that defeats the purpose of dynamic invocation in the first place.

The fix is to change var to dynamic:

dynamic listResult = tgtObj.GetType().GetMethod("GetSomeData").Invoke(tgtObj, null);

Since dynamic bypasses static type checking at compile time, we don't get a compile error. Then, when the dynamic object gets passed to the Export method, the DLR (Dynamic Language Runtime) looks to see if it can implicitly cast the object to meet the requirements of the method signature. Which of course it can.

Ok, so that's how things work in C#. With VB, the line goes like this:

Dim listResult = tgtObj.GetType().GetMethod("GetSomeData").Invoke(tgtObj, Nothing)

With Option Strict On, this line upsets the compiler, as expected. With it off, it works fine. In other words, in VB, I have to turn off the type checker for the entire module that contains the line. There is no finer granularity than that.

Solution 4

You can turn Option Infer On and Option Strict Off and still have something very close.

Solution 5

The equivalent of the c# dynamic keyword in Vb.Net with option strict on exists as a NuGet package: Dynamitey .

After install-package Dynamitey, one can write Vb.Net code as follows:

Option Strict On : Option Infer On : Option Explicit On
Imports Dynamitey
Module Module1
    Public Sub Main()
        Dim o = Nothing
        o = "1234567890"
        Console.WriteLine(Dynamic.InvokeMember(o, "Substring", 5)) ' writes 67890
    End Sub
End Module

Or the slighly more readable:

Option Strict On : Option Infer On : Option Explicit On
Imports Dynamitey
Module Module1
    <Extension()>
    Public Function Substring(self As Object, offset As Integer) As String
        Return CType(Dynamic.InvokeMember(self, "Substring", offset), String)
    End Function

    Public Sub Main()
        Dim o = Nothing
        o = "1234567890"
        Console.WriteLine(Substring(o, 5)) ' writes 67890
    End Sub
End Module

Tested with VS2017 and .net Framework 4.7.2 .

Share:
59,942

Related videos on Youtube

jeroenh
Author by

jeroenh

Technical Architect &amp; Software Engineer

Updated on July 05, 2022

Comments

  • jeroenh
    jeroenh almost 2 years

    Is there an equivalent for the C# 4 'dynamic' keyword when using type safe VB.NET, i.e. with Option Strict On?

    • John K
      John K about 14 years
      VB is type safe whether Option Strict on On or Off. Read about the meaning here msdn.microsoft.com/en-us/library/hbzz1a9a(VS.80).aspx
    • jeroenh
      jeroenh about 14 years
      @jdk ok I guess I'll have to agree. However I meant compile-time checked type safety, as you might have guessed...
    • Mauricio Scheffer
      Mauricio Scheffer almost 14 years
      @jdk: the definition of type safety that everyone uses when talking about programming languages is this one: en.wikipedia.org/wiki/Type_safety
    • John K
      John K almost 14 years
      @Mauricio: I cringe slightly when Wiki is cited, however in context of the author's question of .NET programming Microsoft's definition that I originally linked to suffices more than enough as they are the creators of the framework and semantics that go with it.
    • Mauricio Scheffer
      Mauricio Scheffer almost 14 years
      @jdk: you don't like wikipedia? ok, here are a few more links that say exactly the same, from independent sources: stackoverflow.com/questions/260626/what-is-type-safe nice.sourceforge.net/safety.html lambda-the-ultimate.org/node/1112#comment-12017 c2.com/cgi/wiki?StaticTypeSafety
    • Mauricio Scheffer
      Mauricio Scheffer almost 14 years
      @jdk: Microsoft's definition is about the CLR, not about the languages, which was what the OP was asking about.
    • John K
      John K almost 14 years
      @Mauricio, The link applies to Key Security Concepts in the .NET framework, not specifically the CLR. CLR is one part of the framework. See here for more info msdn.microsoft.com/en-us/library/ms973842.aspx. There's no need for more generalization when this question is in context of .NET. CTS is important too because it's where language data types meet BCL types... but too long to blog about here :)
    • MarkJ
      MarkJ almost 14 years
      @jeroenh I was inspired to post a suggestion on Microsoft Connect that it would be nice if VB had something like dynamic in C#. Anyone who agrees or disagrees can vote or comment on Microsoft Connect here
    • MarkJ
      MarkJ over 13 years
      The Microsoft VB spec lead has just blogged about this idea. The provisional evaluation from the VB team is "VB has always had its own form late-binding via Object. While it’s a shame that you can’t scope your late-binding smaller than file granularity, this doesn’t seem a big enough problem to justify a second form of late-binding." Dear reader, if you feel strongly about this why not leave a comment on the blog, or on the Microsoft Connect issue mentioned in my earlier comment.
    • MarkJ
      MarkJ about 13 years
  • jeroenh
    jeroenh about 14 years
    @Hans Passant: I know that, however C# dynamic is not quite the same as VB's 'late binding'. In C#, with the dynamic keyword I can be very explicit about the dynamic parts of my program. To me it's like telling the compiler: "hey, I know what I'm doing for this specific part of my program". With VB.Net I have to turn off Option Strict for my whole project, which can lead to subtle bugs creeping in because of it.
  • MarkJ
    MarkJ almost 14 years
    @Hans @jeroen. In your edited code, app is inferred as type Object, so it's not possible to use the Excel Application object app. For instance if I substitute app.Calculate where you have REM etc... it doesn't compile. I think this is the problem jeroen is asking about. The compiler says Error 1 Option Strict On disallows late binding.
  • user1703401
    user1703401 almost 14 years
    @MarkJ - you are absolutely right. I checked the VB.NET version 10 Language Specification to be sure. Shockingly the DLR is not mentioned anywhere. Option Strict Off looks completely unavoidable. My apologies for the poor answer.
  • MarkJ
    MarkJ almost 14 years
    @Hans It's easily overlooked. The MSDN documentation really downplays the necessity of using Option Strict Off. Apparently it's possible to write a whole walkthrough without mentioning it, and only mention it briefly in a comment in sample code when discussing early and late binding. I think perhaps they are embarassed?
  • MarkJ
    MarkJ almost 14 years
    I was inspired to post a suggestion on Microsoft Connect that VB should have something like dynamic. Anyone who agrees or disagrees strongly can vote or comment on Microsoft Connect here
  • jeroenh
    jeroenh almost 14 years
    @MarkJ doubt whether this will get through, but it's certainly worth a shot
  • MarkJ
    MarkJ over 13 years
    The Microsoft VB spec lead has blogged about this idea. The provisional evaluation from the VB team is "VB has always had its own form late-binding via Object. While it’s a shame that you can’t scope your late-binding smaller than file granularity, this doesn’t seem a big enough problem to justify a second form of late-binding." Dear reader, if you feel strongly about this why not leave a comment on the blog, or on the Microsoft Connect issue mentioned in my earlier comment.
  • Mark Hurd
    Mark Hurd almost 12 years
    @jeroenh You can override the project-level options at a file-level with different Option directives at the top of the file.
  • Pat
    Pat almost 11 years
    Except it's not exactly the same. For instance, I couldn't figure out how to dynamically invoke a method (see stackoverflow.com/questions/17819977/…) like you can in C#.
  • Basic
    Basic almost 10 years
    More to the point, the C# model allows you to make an exception for a specific object, the VB model forces you to do it far less granularly
  • Sehnsucht
    Sehnsucht almost 8 years
    I know it's an old question but there is a way to do late binding and keeping Option Strict. From the project properties, Compile tab we can set Late Binding to "None" (and Option Strict take the state "Custom") allowing to do Late Binding in a safer environment than setting it to Off
  • Brain2000
    Brain2000 about 7 years
    You dynamically invoke a method in vb.net on an object by just calling it. Make sure to include parenthesis of course.
  • Brain2000
    Brain2000 about 7 years
    The ExpandoObject seems to utilize an IDictionary(Of string, object) under the hood. Interesting.
  • Nick
    Nick almost 7 years
    The question asks for how to do it with Option Strict On. Your answer only works with Option Strict Off
  • ryanwebjackson
    ryanwebjackson over 6 years
    CallByName - Should help any web searchers out there: docs.microsoft.com/en-us/dotnet/visual-basic/programming-gui‌​de/…