Error in VB compiler and / or IntelliSense in both C # and VB WRT. Regardless of the range of properties and parameters ByRef fn ()

I noticed some seemingly strange problems in Visual Studio 2008 (.NET 3.5) as well as in Visual Studio 2010 Beta 2 (.NET 4.0). These problems may have existed in previous versions. Perhaps this is not a problem, but in any case, I would like to know if there are logical explanations for this before I submit a report on Microsoft Connect.

Customization (in VB, C # results differ and are included later in the message):

Public Class SomeClass Public Property SomeProperty() As String Get Return String.Empty End Get Set(ByVal value As String) End Set End Property End Class Public Class SomeOtherClass Public Sub New() Dim sc As New SomeClass() Me.SomeFunction(sc.SomeProperty) End Sub ''' <summary>The param as Object fn()</summary> ''' Public Sub SomeFunction(ByVal param As Object) End Sub ''' <summary>The param as T fn()</summary> ''' Public Sub SomeFunction(Of T)(ByRef param As T) End Sub End Class 

In this simulation, calling Me.SomeFunction(sc.SomeProperty) , from the point of view of IntelliSense, looks like this:
alt text
and, unsurprisingly, this is also what gets called at runtime.

So, I assume that I have the first question , why was the version of the overloaded version of ByRef selected for the function selected over the version of the function of overloading the ByVal object? I assume that the compiler and IntelliSense simply approve template versions compared to non-templated versions. At run time, this is actually a boilerplate version of the ByRef function that is called. (This is not a defect, it is just a personal question to know.)

Now make a small change to the SomeProperty property SomeProperty that the setter is now closed:

 Public Property SomeProperty() As String Get Return String.Empty End Get Private Set(ByVal value As String) End Set End Property 

Once you do this, the following will happen in the line Me.SomeFunction(sc.SomeProperty) :
alt text

In this case, IntelliSense assumes that the ByVal Object overload function is called, however the error message the 'Set' accessor of property 'SomeProperty' is not accessible indicates that the compiler is still waiting for a template version of ByRef to be called. So this is my second question . Why is Intellisense claiming one thing while the VB compiler is explicitly trying something else? It seems to me broken. Or am I missing something?

If instead of having a private setter in SomeProperty , but instead the ReadOnly property was just marked and the setter part was removed, the templated version of the ByRef function is shown in IntelliSense and is called at run time (without errors at run time). Thus, this leads me to my third question , why does the VB compiler handle ByRef input parameters that are different for properties that are ReadOnly vs not-ReadOnly but have settings out of scope in VB As since SomeFunction (Of T) (.. .) is related to the current scope, this property should be as if it were ReadOnly, and I would expect it to be called as if this property were really ReadOnly. But instead, it creates a build error.

In correlation with question three, performing the same setup (using the Private setter), C # has the result I was expecting. alt text
Here you can see that IntelliSense claims to cause an overload of the SomeFunction (Object) function, and there is no build error. At run time, the version of SomeFunction (Object) is actually called. So why in a VB.NET situation the same SomeFunction (Object) version is not called? Why does VB.NET still think it is necessary to call the version of SomeFunction (Of T) (ByRef T)? It looks like IntelliSense is correctly stuffing it in both C # and VB.NET, the C # compiler is doing everything right, but the VB.NET compiler is still convinced that it should invoke the ByRef template version. It seems to me that the C # compiler chooses one overload, and the VB.NET compiler chooses another overload in the same situation. I am wrong?

+4
source share
2 answers

Regarding your third question:

Why does the VB compiler handle ByRef input parameters that are different for properties that are ReadOnly vs not-ReadOnly but have a parameter out of scope in VB

In the CLR, you cannot pass a property as ByRef. However, the VB.NET team decided that it would be useful and implemented in a workaround. Inside

 Me.SomeFunction(sc.SomeProperty) 

converted to

 Dim vbTemp = sc.SomeProperty Me.SomeFunction(vbTemp) 

which is called Dont Copy Back ByRef and is used, for example, for read-only properties or

 Dim vbTemp = sc.SomeProperty Me.SomeFunction(vbTemp) sc.SomeProperty = vbTemp 

which is called Copy Back ByRef and is used for properties containing both getter and setter. All of these things (and a few more complicated cases) are explained in jaredpar WebLog: many ByRef cases .

Now you say that when the setter goes out of scope, Dont Copy Back ByRef should be executed. However, this will lead to inconsistent behavior: SomeFunction(sc.SomeProperty) will update sc.SomeProperty when called inside SomeClass , but the same line of code will silently update the property when called outside (since the setter is out of scope).


About the first and second question:

Why was the version of the overloaded ByRef function for the function selected above the version of the ByVal Object function for the function changed? I assume that the compiler and IntelliSense simply approve template versions compared to non-templated versions.

They prefer templated versions over the version that requires an extension to Object . Overload resolution is described in detail in Chapter 11.8.1 of the Visual Basic Language Specification .

Why is Intellisense claiming one thing while the VB compiler is explicitly trying something else?

Looks like a mistake.

+6
source

If it is possible that they choose different versions - overload resolution is a complex area that is described in detail in the specification documents. For example, you need to specify in which order the use of generics, the use of implicit cases / transforms / boxing, etc. should be considered.

Also - remember that in C # ref must be explicit , so the ref version is not even a valid code overload. In VB, it is implicit and (via the generic version) can use exact match without any casts / etc conversions.

Confusingly, it may be that overload resolution occurs before the availability check, so the private thing (by itself) is not surprising.

I also don't think that intellisense necessarily defines the version that is actually being called - it is only the overload of s that are available.

0
source

Source: https://habr.com/ru/post/1299261/


All Articles