-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[VB.NET] Wrong assignments to interfaces do compile #48387
Comments
I don't see anything in the spec that would cause errors here in the cases you've mentioned. There it says:
Which indicates that non-strict semantics narrowing conversions without an explicit cast are allowed. The conversions spec says this about narrowing conversions:
So this seems by design. You have option-strict off. So narrowing conversions without an explicit cast are not disallowed. |
I'm going to close this out as Roslyn seems to be working as expected. If you disagree please let me know, including links to the appropriate places in the spec that you think the impl contradicts. If you do not like how the specification works here, then the appropriate thing to do is open an issue at dotnet/vblang. Thanks! |
S, why VB refused this:
despite that short can be safely widened to integer. This applies also even if one of the two types inherits the other.
and VB refused it! |
Please Don't close issues before hearing the response on your answer. This is defiantly a bug or at least misbehaviour. |
@AdamSpeight2008 @paul1956 @Happypig375 @pricerc @hartmair @franzalex @gilfusion |
That doesn't appear to be a narrowing conversion. Afaict, there is no conversion that would allow that. So this isn't allowed because the language has no conversion that for at all. Option strict on/off is about if narrowing conversions are allowed are not. |
If you can point to the part of the spec that you feel demonstrate that, please let me know and i can reopen. Thanks! :) |
That's literally what the spec on conversions says:
:) And option-strict-on is what causes you to get errors if you have a narrowing conversion without an explicit cast. Since you are in option-strict-off, i'm not seeing what part of the spec says this should be disallowed. Please point to what you think would disallow this. Thank you :) |
This is exactly the case in other wrongly accepted codes! |
What do you mean? The spec here says: https://github.com/dotnet/vblang/blob/master/spec/conversions.md#reference-conversions
There is no defined conversion between Foo1 and foo2. There are defined conversions between If you believe otherwise point out why using the specification. I have linked exactly to the points in the spec i think are relevant here. You cannot simply state you disagree. You have to actually give the exact sspec reasons why this is incorrect. |
You seem to totally miss the point: |
Yes it does. I just pointed to the part of the spec that allows this. Again, it is right here: https://github.com/dotnet/vblang/blob/master/spec/conversions.md#reference-conversions
https://github.com/dotnet/vblang/blob/master/spec/conversions.md#narrowing-conversions
It says so right there. Any class or interface type can be converted to and from any interface type. That is exactly the case we have here. And it's a narrowing conversion when the class type does not implement the interface type. |
IList/IQueryable/IEnumerable are all interfaces. The specification says that any class/interface type can be converted to/from them.
Specification requests are not filed at dotnet/roslyn. If you want the specification changed, please file an issue at dotnet/vblang. :) |
And here is another point to check in specs: |
The spec does deal with it. I have linked to where it is dealt with. :) If you do not like how the specification deals with it, then the appropriate thing to do is to open an issue at dotnet/vblang where you can put forth a design on how the language should change. Right now the compiler (dotnet/roslyn) seems to be implementing the language properly. |
|
Let me rephrase: |
Feel free to point to where you think the spec says this. If you are correct, i will reactivate the issue. Absent that, i'm going to keep the issue closed as i can't find anything in the spec supporting that statement. |
Yes. You have not enabled
With
As i've pointed out, the spec says: Class and interface types can be cast to and from any interface type. It explicitly calls out that there is a reference conversion between any two interfaces. And it points out when this is a narrowing conversion. If you do not enable This is why |
This comment has been minimized.
This comment has been minimized.
@VBAndCs i think you really should read through the spec. Of high relevance is this part:
You are using permissive semantics. So all narrowing conversions may occur implicitly. The examples you have given are all narrowing conversions. So they are allowed. If you don't want that, use |
@VBAndCs I have hidden your question for being off topic. If you have questions about that issue, please use that issue to discuss them. Thanks. Alternatively, you can discuss it on gitter or discord. Please don't use other issues to discuss things unrelated to them. Thanks! :) |
Imports System
Class Foo1
Shared Sub Main()
Dim x As IDisposable
Dim y As Foo1 = New Foo2
x = y ' Perfectly acceptable
Console.WriteLine(x)
y = New Foo1
x = y ' Try again: InvalidCastException
End Sub
End Class
Class Foo2
Inherits Foo1
Implements IDisposable
Sub Dispose() Implements IDisposable.Dispose
End Sub
End Class |
The compiler may expect to have a narrowing in runtime, if only the opposite conversion is widening. Dealing with generic interfaces, must force VB to check the generic types, not only the interfaces types, and here Foo1 and Foo2 doesn't have a widening operation to expect they may have a narrowing one in runtime. VB refuses to cast each of them to each other, so, defiantly it must do the same with a generic interface having them as generic types. |
I honestly don't know what you're asking for. As i've pointed out, the compiler seems to be operating as per the spec. If you disagree you must point out the particular parts of the spc that you think it is violating. Absent that there will be no further movement on this topic. Again, if you do not actually point out the spec violation that is occurring, nothing will change here. Also, when i say "point out" i mean: provide an actual hyperlink to the section of the spec in question, or an actual quote from the spec. Saying you disagree or that you don't like this does not suffice. |
I see nothing in the spec that says this is how things work. The spec is explicit here and refers to "interfaces" as a whole. That means it applies to both normal interfaces and generic interfaces. So the same rules apply for those. If you feel otherwise, you must link/quote the section of the specification you feel supports your position. Further comments that do not do this will not be acted on. |
Since I was asked for an opinion. This is an excellent example of why As far as I'm concerned @VBAndCs if VB was being re-imagined today, I would expect there to be no |
@pricerc
The third mode is the most useful and make coding faster but still safe with less errors. This is not a legacy as you think. This is the default settings for the language, meaning that it is encouraged or at least asked for by most developers. |
You're welcome to totally disagree. I'm just giving you my opinion :) (which you asked for :) ) Which comes from my personal experience dealing with hundreds of VB/VBA programs from different people, for over 20 years. I'm sure there was a discussion somewhere about changing the VB defaults for Strict. I wish they would. Because of the environments I support, I have about 10 different active virtual environments with Visual Studio installed, and I regularly have to retire and replace them with new ones. So I always pretty much have VS in its default settings. But changing the option strict is something I do on all my projects, and one of the first things I do if I'm asked to take over someone else's work. It is one of the quickest ways to find weird problems. For me, it's (side note: for text comparisons, I have gotten into the habit of using String.Compare in both C# and VB, because that's what StyleCop/FxCop (can't remember which) typically recommends, so the |
You say it's safe with less errors. But you also don't like that it's unsafe and make these conversion errors. If you don't like that conversion errors then turn on option strict. |
@CyrusNajmabadi |
It's literally why this option exists :-)
It is. But that's why you can turn on this option. It is literally the option you can turn in to say you want this behavior. We can't make this behavior the default because it would literally break customers all over the ecosystem. |
Ironically, I'm sure I've seen the exact opposite argument somewhere, where someone was complaining about VB's default 'strict off' behaviour, and why that made VB an inferior language. Which goes to show, you can't please all of the people all of the time. |
@pricerc LOVE VB, HATE Strict Off you can believe both. |
Consider this: Module Module1
Sub Main()
Dim x As IList(Of Foo1)
Dim y As Foo2 = New Foo2()
Try
x = y ' compiles!
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
y = New Foo2Derived()
x = y
x = New List(Of Foo2) ' compiles
End Sub
End Module
Class Foo1
End Class
Class Foo2
End Class
Class Foo2Derived
Inherits Foo2
Implements IList(Of Foo1)
Public Function IndexOf(item As Foo1) As Integer Implements IList(Of Foo1).IndexOf
Throw New NotImplementedException()
End Function
Public Sub Insert(index As Integer, item As Foo1) Implements IList(Of Foo1).Insert
Throw New NotImplementedException()
End Sub
Public Sub RemoveAt(index As Integer) Implements IList(Of Foo1).RemoveAt
Throw New NotImplementedException()
End Sub
Default Public Property Item(index As Integer) As Foo1 Implements IList(Of Foo1).Item
Get
End Get
Set(value As Foo1)
End Set
End Property
Public Sub Add(item As Foo1) Implements ICollection(Of Foo1).Add
Throw New NotImplementedException()
End Sub
Public Sub Clear() Implements ICollection(Of Foo1).Clear
Throw New NotImplementedException()
End Sub
Public Function Contains(item As Foo1) As Boolean Implements ICollection(Of Foo1).Contains
Throw New NotImplementedException()
End Function
Public Sub CopyTo(array() As Foo1, arrayIndex As Integer) Implements ICollection(Of Foo1).CopyTo
Throw New NotImplementedException()
End Sub
Public Function Remove(item As Foo1) As Boolean Implements ICollection(Of Foo1).Remove
Throw New NotImplementedException()
End Function
Public ReadOnly Property Count As Integer Implements ICollection(Of Foo1).Count
Public ReadOnly Property IsReadOnly As Boolean Implements ICollection(Of Foo1).IsReadOnly
Public Function GetEnumerator() As IEnumerator(Of Foo1) Implements IEnumerable(Of Foo1).GetEnumerator
Throw New NotImplementedException()
End Function
Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
Throw New NotImplementedException()
End Function
End Class In short, forget about the expression being a
A cast that truly is provably impossible will still be an error regardless of the However, because of COM interop (and something else I think) it's still technically possible for a
|
@AnthonyDGreen |
In design time, when
Option Strict off
, all assignments to interfaces are OK, even it is obviously impossible because the class doesn't implement the interface. I tested with IEnumerable, IQueryable, and IList. This code sample compiles correctly (and it must not) but gives runtime errors of course!Note:
This code will not compile as expected:
Is there any case that a class that doesn't implement the interface can be cast to it? I have no knowledge of that.
Note that this issue applies also when assigning
IQueryable(Of Foo2)
toIQueryable(Of Foo1)
. VB refuseDim y As Foo1 = New foo2
even whenOption Strict off
, so, why it accepts:The text was updated successfully, but these errors were encountered: