Я заметил некоторые, казалось бы, странные проблемы в Visual Studio 2008 (.NET 3.5), а также в Visual Studio 2010 Beta 2 (.NET 4.0). Эти проблемы могли существовать и в предыдущих версиях. Возможно, они не являются проблемой, но в любом случае я хотел бы узнать, есть ли для них логические объяснения, прежде чем я отправлю отчет в Microsoft Connect.
Настройка (в VB, C # результаты отличаются и включены позже в пост):
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
В этом случае вызов Me.SomeFunction(sc.SomeProperty)
с точки зрения IntelliSense выглядит следующим образом:
и, что неудивительно, это также то, что называется во время выполнения.
Итак, я думаю, первый вопрос , который у меня есть, , почему была выбрана версия функции ByRef с перегрузкой, выбранная из версии функции перегрузки ByVal Object? Я предполагаю, что что компилятор и IntelliSense просто предпочитают шаблонные версии по сравнению с не шаблонными версиями. Во время выполнения вызывается только шаблонная версия функции ByRef. (Это не дефект, это просто личный вопрос, который нужно знать.)
Теперь внесите небольшое изменение в свойство SomeProperty
, чтобы установщик стал приватным:
Public Property SomeProperty() As String
Get
Return String.Empty
End Get
Private Set(ByVal value As String)
End Set
End Property
Как только вы это сделаете, со строкой Me.SomeFunction(sc.SomeProperty)
произойдет следующее:
В этом случае IntelliSense предполагает, что вызывается версия функции ByVal, перегруженная объектом, однако появляется сообщение об ошибке the 'Set' accessor of property 'SomeProperty' is not accessible
, указывающее, что компилятор все еще ожидает вызова шаблонной версии ByRef. Итак, это мой второй вопрос . Почему Intellisense требует одного, а VB-компилятор явно пытается что-то другое? Мне кажется, что это не так. Или я что-то упустил?
Если вместо SomeProperty
имеется закрытый установщик, но вместо этого свойство просто помечено как ReadOnly, а установщик удален, то шаблонная версия ByRef функции отображается в IntelliSense и вызывается во время выполнения (без ошибок во время выполнения) ). Таким образом, это приводит меня к моему третьему вопросу , , почему компилятор VB обрабатывает входные данные для параметров ByRef для свойств, которые являются ReadOnly и not-ReadOnly, но имеют установщик вне области видимости в VB Что касается SomeFunction (Of T) (...), то в его текущей области это свойство должно быть таким, как если бы оно было ReadOnly, и я ожидаю, что оно будет вызываться так же, как если бы это свойство было на самом деле ReadOnly. Но вместо этого он выдает ошибку сборки.
В связи с третьим вопросом, при выполнении точно такой же настройки (с частным сеттером), C # имеет ожидаемый результат.
Здесь вы можете видеть, что IntelliSense утверждает, что вызывается перегрузка функции SomeFunction (Object), и нет ошибки сборки. Во время выполнения версия SomeFunction (Object) фактически вызывается. Итак, почему в ситуации VB.NET не вызывается та же версия SomeFunction (Object)? Почему VB.NET до сих пор считает, что нужно вызвать версию SomeFunction (Of T) (ByRef T)? Похоже, что IntelliSense правильно прибивает это как в C #, так и в VB.NET, компилятор C # делает правильные вещи, но компилятор VB.NET по-прежнему убежден, что он должен вызывать шаблонную версию ByRef. Мне кажется, что компилятор C # выбирает одну перегрузку, в то время как компилятор VB.NET выбирает другую перегрузку в точно такой же ситуации. Я не прав?