Разница между VB.Net и С# "Как новый WebControl"
Я пересматривал код, и часть его включала перемещение его с VB.Net на С#.
Старый код объявляет такой элемент:
Protected viewMode As New WebControl
Новый код, в конце концов я получил работу, например:
protected WebControl _viewMode = new WebControl(HtmlTextWriterTag.Span);
Я могу предположить, что ключевое слово New
означает: вызвать конструктор! Но как VB.Net вызывал конструктор (без параметра), который я не мог вызывать на С#?
Ответы
Ответ 1
Причина, по которой это работало в VB, а не в С#, не имеет ничего общего с сборками.
Конструктор по умолчанию для WebControl защищен.
VB и С# имеют разные интерпретации того, что означает "защищенный".
В VB вы можете получить доступ к защищенному члену класса из любого метода любого типа, который выводится из класса.
То есть, VB позволяет компилировать этот код:
class Base
protected m_x as integer
end class
class Derived1
inherits Base
public sub Foo(other as Base)
other.m_x = 2
end sub
end class
class Derived2
inherits Base
end class
Поскольку "Derived1" является базой, он может получить доступ к защищенным членам "other", который также является базой.
С# использует другую точку зрения. Это не позволяет "боковым" доступом, что делает VB.
В нем говорится, что доступ к защищенным членам может осуществляться через "this" или любой объект того же типа, что и класс, содержащий этот метод.
Поскольку "Foo" здесь определен в "Derived1", С# разрешает "Foo" получать доступ к элементам "Base" из экземпляра "Derived1". Возможно, что "другое" является чем-то, что не является "Derived1" (может быть, например, "Derived2" ), и поэтому он не разрешает доступ к "m_x".
В этом случае ваш код, VB разрешил "боком" доступ к конструктору "WebControl".
С#, однако, не сделал.
Ответ 2
Конструктор по умолчанию для WebControl (неявный в строке VB) должен использовать span. Вы можете вызвать этот конструктор в С#, а также VB.NET.
Ответ 3
Доступ к унаследованным защищенным конструкторам из производного класса в любом контексте может вызвать проблемы инкапсуляции данных.
Исторически, С#, так как первая версия допускала такой доступ. Но это было исправлено в VS 2005 года. Производные классы могут теперь ссылаться на свои базовые защищенные конструкторы только со своего собственного конструктора.
class Base
{
protected Base()
{
}
}
class Derived : Base
{
public Derived() : base() // Still allowed in VS 2005
{
}
public void Main()
{
Base b = new Base(); // Allowed in VS 2003, but error in VS 2005
}
}
В VB.NET вы можете инициализировать переменные двумя способами. Сначала с оператором присваивания следует декларация; второй с инструкцией "Как новый".
В случае защищенного конструктора "As New" всегда работает нормально. Что касается инициализации по заданию, это вызовет ошибку компиляции. Но если у вас есть несколько конструкторов в базовом классе, инициализация присваивания также будет работать!
Class Base
Protected Sub New()
End Sub
End Class
Class Derived
Inherits Base
Public Sub Main()
Dim foo As New Base // Allowed
Dim moo As Base = New Base() // Error if Base has only one constructor
End Sub
End Class
Вероятно, причина, по которой VB.NET позволяет этот вид доступа совместим с устаревшим кодом.
Подробнее: http://blogs.msdn.com/b/peterhal/archive/2005/06/29/434070.aspx
Ответ 4
Webcontrol wc = tab;