Разница между 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;