Partager via


Core3: Dynamic pseudo-type (scoped late binding)

[This post is part of a series, "wish-list for future versions of VB"]

 

IDEA: Scoped late binding through a dynamic pseudo-type. Add a new pseudo-type called either Dynamic or Variant. It would be exactly the same type as Object, but it would suppress errors/warnings about late-binding in any expression that it’s used. Also, when we import COM functions that currently return Object, we’d import them instead as returning Dynamic. We’d also use the same DynamicAttribute that C# uses when reading or writing metadata.


SCENARIO: You want to have late-binding in your code, but want to leave Option Strict On. Currently there’s no way to do this. The dynamic pseudo-type would allow it, as shown below. In the following we’ve written “As Dynamic” explicitly to show what type we’re getting back (and it suppresses errors/warnings on “cell.ColumnWidth”), but if we omitted it then "cell" would still be inferred as Dynamic.

    Option Strict On

    Dim excel = New Microsoft.Office.Interop.Excel.Application

    excel.Visible = True : excel.Workbooks.Add() : excel.Worksheets.Add()

    Dim cell As Dynamic = excel.Cells(1, 1)

    cell.ColumnWidth = 15

 

Note that this wouldn’t quite be the same as the C# “dynamic” pseudo-type. The C# rules say “If dynamic is involved anywhere then do a late-bound call”. But the existing VB rules say “If binding failed, and it failed due to narrowings from Object, then do a late-bound call”. We would stick with the VB rules for our dynamic pseudo-type. For instance,

        Dim d As Dynamic = "hello"

        Console.WriteLine(d) ' early-bound call in VB

 

        dynamic d = "hello";

        Console.WriteLine(d); // late-bound call in C#

ALTERNATIVE IDEA: Instead of using a pseudo-type to suppress errors/warnings about late-binding, we could instead use different operators:

        cell~.ColumnWidth = 15

        ' The "~." operator is like "." but it suppresses
' warnings/errors about late-binding

 

An entirely different way to achieve “scoped late-binding” is to add #Pragma directives to VB which could suppress arbitrary errors/warnings in any chunk of code. I’ll take about this later (“Req33: Pragmas, e.g. to suppress warnings”).

 

 

Provisional evaluation from VB team: 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.

Comments

  • Anonymous
    January 28, 2010
    I guess I'm wondering what the advantage is over just implementing the Dynamic keyword in VB exactly the same as in C#, in such a way that it would be compatible with Option Strict On.  (That is, Option Strict violation errors wouldn't be raised on things typed as Dynamic.) I assume you'd have to specifically type something as Dynamic if Option Infer were on. I think the alternate idea of using ~. looks dreadful. Perhaps another alternate idea:  The ability to declare a LateBound (or Dynamic) block, similar to how C# declares an unsafe block?  E.g.: LateBound    ' do late-bound stuff End LateBound I'd be in favor of just about anything that would keep people from having to make an entire file late-bound.  Just about anything outside of that ugly ~. syntax.  :)

  • Anonymous
    January 28, 2010
    The comment has been removed

  • Anonymous
    January 28, 2010
    I really really like the ~ idea.  It's concise and it marks the late-bindedness where it matters, not in some other place the programmer may forget to check when writing or debugging the code.  Typing all those ~s could be tedious, but the impact is relatively easy to verify by taking existing non-strict code, adding all the ~s where required, and seeing how bad it is.

  • Anonymous
    February 04, 2010
    Didn't VB3 and VB4 use the "!" operator for this?

  • Anonymous
    February 04, 2010
    The ! operator has slightly different purpose. In VB2005/8/10 it looksproperty with following signature: Public Default Property Whatever (ByVal whatever As String) As Whatever on the object on left side. On right it expects identifies and passes it as index parameter to the property. Maybe VB canoverload it for dynamic purposes.

  • Anonymous
    February 04, 2010
    The ! operator has slightly different purpose. In VB2005/8/10 it looksproperty with following signature: Public Default Property Whatever (ByVal whatever As String) As Whatever on the object on left side. On right it expects identifies and passes it as index parameter to the property. Maybe VB canoverload it for dynamic purposes.

  • Anonymous
    February 13, 2010
    This would be very useful - scoping late binding / dynamic typing at the file level means that you lose type checking for all variables, instead of the (usually) one or two you actually need to be dynamic. Even using partial classes to isolate the late bound methods in a class leaves other variables (string, etc.) without compile-time type-checking. I have a class that interacts with a legacy VB6 COM+ application using late binding - used because the IIDs change occasionally, but the relevant method signature never does so early binding would break unnecessarily  (even with binary compatibility VB6 doesn’t entirely preserve interface IDs). To do this I have a file with Option Strict switched off (a massive violation of our standards) just to allow me to late bind to the COM class variable. The other variables in the class (mainly primitives – especially strings) I still want to use early binding with, but I’m forced to use late binding with them all because the binding setting is file scoped. The ideal scoping for late binding is the variable itself – anytime I have ever used this it was specific variables – generally just one or two – and I don’t like losing early type checking for everything else. It’s not a huge issue because I don’t use late binding much in VB, but it would make the language cleaner if we could target late binding where it logically applies – at the variable.

  • Anonymous
    January 05, 2011
    Thanks for considering the idea. I still think it would be really nice to be able to scope late binding at the variable level. It's one of the remaining things that justifies snobbery about VB. Can I also add a couple of links? Not spam, honest! Everyone who likes this idea, please vote for it on Microsoft Connect and maybe it'll get implemented. connect.microsoft.com/.../please-give-vb-net-some-equivalent-for-c-dynamic-with-option-strict-on   Also, there's some more discussion about this on StackOverflow - this discussion prompted me to add the issue on Microsoft Connect stackoverflow.com/.../vb-net-equivalent-for-c-dynamic-with-option-strict-on

  • Anonymous
    January 06, 2011
    I'm all for it. As MarkJ says, this is one of the remaining gaps between VB.Net and C#.

  • Anonymous
    August 11, 2011
    The comment has been removed

  • Anonymous
    November 27, 2012
    We need this if VB is to actually support asp.net mvc properly.

  • Anonymous
    June 02, 2015
    It would be really nice if "As Dynamic" could make it into VB.NET, once the Roslyn dust settles, since the better scoping for late binding is about the only thing I really keep missing in VB.NET vs. C#.

  • Anonymous
    September 04, 2015
    Just one more vote for the variable level scoping of late binding.  We insist on Option Strict On in all our code to prevent sloppy stuff.  There are however situations where a single variable that is late bound would be very useful (think a de-serialized JSON string for example).