2016-08-31 2 views
3

Клиент имеет переменную, объявленную с использованием статического типа - подобный следующему испытанию (который компилирует в VB):Почему VB разрешает объявление объекта статического типа?

Dim test As System.IO.File 

Какова цель этого? В коде моего клиента эта переменная не упоминалась нигде, поэтому я не мог следовать шаблону использования. Я бы ожидал, что у VB возникнет проблема с этим объявлением (как это делает C#), но поскольку я не предполагаю, что для этого существует какая-то эзотерическая цель VB-иш?

+0

@CodyGray: No - VB должно быть предупреждением об объявлении переменной статического типа, которая, как представляется, не имеет никакой цели (это ошибка компиляции в C#). –

+3

Извините. Мне потребовалось некоторое время, чтобы понять, что 'System.IO.File' является статическим классом, поэтому наличие переменной этого типа не имеет смысла. – sstan

+1

К нисходящим - я думаю, что вы поспешны и не очень читаете вопрос. –

ответ

5

Фактически нет такой вещи как Shared класс в VB.NET. (Shared - это ключевое слово VB.NET для того, что мы знаем и любим как static в C#). Только переменные (поля), события, функции/подтипы, свойства и операторы могут быть отмечены Shared. (Локальные переменные, которые сохраняют свои значения во всех вызовах, не отмечены Shared, а скорее Static. CLR не поддерживает их, а также не C#, но компилятор VB.NET испускает дополнительный код, необходимый для его работы.)

есть два пути, чтобы осуществить тот же результат, как статический класс в VB.NET:

  1. Создать Module. Практически это то же самое, что и статический класс. Действительно, с точки зрения ИЛ они идентичны. Тем не менее, модули обрабатываются несколько иначе на языке VB.NET. Концепция модулей была унаследована от устаревших VB на основе COM (на самом деле они намного старше этого, вернувшись к ранним версиям BASIC)

    Если вы знакомы с C++ или подобными языками, модуль сродни пространство имен, за исключением того, что все функции, определенные в модуле, продвигаются во внешнюю область (охватывающее пространство имен) через Microsoft.VisualBasic.CompilerServices.StandardModule attribute. Модуль никогда нельзя рассматривать как класс, поэтому любые объявления или ссылки на модуль являются незаконными. Тем не менее, вы можете (и, как правило, предпочитаете) вызывать функцию, определенную в модуле, с использованием полностью квалифицированной ссылки (, например, MyModule.MyFunction(...)).

  2. Создать NotInheritable класс (VB.NET эквивалент C# s abstract ключевое слово), дать ему пустой Private конструктор, и отметьте все его методы, как Shared. Обратите внимание, что сам класс не является общим/статическим - только отдельные функции, составляющие этот класс. Поэтому компилятор не применяет правило, что экземпляр этого класса нельзя объявить, поскольку с точки зрения компилятора класс не отличается от любого другого класса.

Поскольку .NET BCL была написана на C#, она использует вариант 2. Всех классов, которые были отмечены static просто NotInheritable классов в VB.NET с функциями Shared членов и частными застройщиками. Например, декларация System.IO.File выглядит следующим образом VB.NET:

Public NotInheritable Class File 
    Inherits System.Object 

    ' Contains Shared methods, e.g.: 

    Public Shared Sub Copy(sourceFileName As String, destFileName As String) 
     ' implementation 
    End Sub 

    ' private constructor to prevent instantiation 
    Private Sub New() 
    End Sub 

End Class 

Обратите внимание, что поскольку только конкретизации запрещается (с помощью решений конструктор приватным), компилятор по-прежнему позволяет объявлять пустые переменные, которые тип класса. Разумеется, им никогда не может быть присвоено значение, поэтому они всегда будут равны Nothing.(TypeOf(test) Is Nothing вернет True, в этом случае, как и test Is Nothing, и TypeName(test) вернет Nothing).

+0

... и это еще раз доказывает, что если вы попытаетесь создать экземпляр 'test = New System.IO.File 'он будет терпеть неудачу, потому что' Type 'System.IO.File' не имеет конструкторов', а не потому, что это статический класс. (Таким образом, вы должны, вероятно, добавить к этому примеру частный конструктор.) – GSerg

+1

@GSerg Работая над этим во время написания комментария. Совершено сейчас. :-) Был * очень * долгое время с тех пор, как я работал в VB. –

+0

Я принял ваш ответ, но я думаю, что VB * должен уметь смотреть на это и заметить, что это смехотворное заявление. Единственное, что может быть объектом статического типа, это объект без ссылок. Ему ничего нельзя назначить и ничего не получить. –

Смежные вопросы