vblang
vblang copied to clipboard
Implicitly casting IEnumerable(Of T) to List(Of T) should either be a compile time error or call ToList() on the input sequence.
If I write this code:
Dim list As New List(Of String)
list = List.OrderBy(Function(q) q)()
Then I get a rather cryptic runtime error about a "state machine". The actual problem is that I'm trying to implicitly cast an IEnumerable(Of String)
to a List(Of String)
. But why should this be a runtime error? Can't it be a compile time error, same as any other invalid conversion? This is how C# behaves. Or if you want to be more VB-paradigmatic, why not call ToList()
on the sequence implicitly when this cast is performed? At the very least, if it has to be a runtime error, why can't the error message be clearer, saying something about an invalid cast from IEnumerable(Of T)
to List(Of T)
, rather than some sort of state machine?
Thanks! 🙂
I'm pretty sure that I get warnings in my editor about this, which I'm sure is a very common pattern; I know I use it a lot.
What options are you running your VB compiler with?
why not call
ToList()
on the sequence implicitly when this cast is performed?
Because the VB compiler needs the framework to provide the necessary converter, which it apparently doesn't.
I think there is a good case to make that List(Of T)
should have an implicit cast from IEnumerable(Of T)
.
The code only compiles with Option Strict Off
; with Option Strict On
I get the following compilation error:
BC30512: Option Strict On disallows implicit conversions from 'IOrderedEnumerable(Of String)' to 'List(Of String)'.
I think there is a good case to make that
List(Of T)
should have an implicit cast fromIEnumerable(Of T)
.
There is a significant difference between IEnumerable(Of T)
and List(Of T)
-- List(Of T)
contains all the values in memory. Although IEnumerable(Of T)
contains all the information needed to produce those values, they may not have been produced yet (although they might have been -- e.g. a compile-time expression of type IEnumerable(Of T)
can reference a List(Of T)
). Having an implicit cast from IEnumerable(Of T)
to List(Of T)
means the compiler wouldn't warn about the possibly unwanted evaluation of all these values.
Particularly when you're building up a LINQ query with multiple assignments, you only want the query to be evaluated at the end. There would be no way to write something like that if there were such an implicit cast.
Considering that using Option Strict On
it's a compiler error, and the fix is rather simple (just call ToList()
), I think this would be a bad idea.
Oh, enabling Option Strict
will make this a compile error? That's handy! I can enable Option Strict
for just one code file by placing Option Strict On
at the top of that file, right? I'm hesitant to enable it for the entire project because it's a large legacy codebase and doing so would probably expose numerous errors that do need to be fixed eventually but I wouldn't have time to fix them all right now...
"Option Strict Off" setting does not allow you to find potential bugs at compile time.
It is recommended to make improvements on a module-by-module basis, even when there are changes to the module.
Stay away from any fancy feature that use machine state or interface when you coding VB.net because VB.net intellisense isn't up to date on those feature, even Static N As Integer = 1
still use very old code from VS 2015 era.
Static N as Integer =1
is just fine as far as I know, what is your problem with it?
What about support for VB.Net to have access to full library or at least DeserializeObject if not all functions. Serialization seems to be compatible.
@jrmoreno1 They still use very slow Activator
instead anonymous static field like Static N as Integer
without initialize.
@RevensofT : not sure what you mean, part of the spec for Static is that it has to be thread safe and when assigned a value as part of the declaration, that code will only run once. Presumably they could replace the System.Activator.CreateInstance, with something else, but it wouldn't be a simple as Shared N as Integer
.
@jrmoreno1 Just use Nullable(Of T)
instead Activator
, with nullable compiler can check static var has been initialized easily and faster then Activator
.