Сообщений 0    Оценка 240        Оценить  
Система Orphus

Что нового в VB.NET Whidbey?

Автор: Алексей Ширшов
The RSDN Group

Источник: RSDN Magazine #1-2004
Опубликовано: 16.07.2004
Исправлено: 10.12.2016
Версия текста: 1.0
Введение
Новые языковые конструкции
Перегрузка операторов
Новые типы
Новые инструкции
Частичные типы (partial types)
Нововведения CLR 1.2
Generics
Generic-классы
Generic-методы
Generic-делегаты
Generic-операторы
Нововведения, которых пока нет :)
Другое
Документация
Пространство имен My
Заключение

Введение

Не за горами появление новой версии Visual Studio 8.0, которая носит кодовое имя Whidbey. В ней (и вместе с ней) будет большое количество изменений, часть из которых касается CLR, языков, дизайнеров и графического интерфейса. Данная статья посвящена изменениям в компиляторе Visual Basic.NET. Все эксперименты проводились на так называемой PDC release-версии VS – Visual Studio 8.0.30703.4. Версия .NET Framework – 1.2.30703.

Новые языковые конструкции

В данном разделе описываются нововведения в языке, которые не касаются новых возможностей CLR. Описываемые конструкции могли появиться и раньше, однако по тем или иным причинам они отсутствовали в языке, что вызывало много нареканий и критики. Ну, что ж, всему свое время: Visual Basic развивается эволюционным путем, и это не может не радовать.

Перегрузка операторов

Перегрузка операторов достигается за счет использования новой инструкции (statement) языка: operator. Вот ее синтаксис:

[ <attrlist> ] PublicShared [ Widening | Narrowing ] 
Operator operatorsymbol ( operand1 [, operand2 ]) [ As [ <attrlist> ] type ]
  [ statements ]
  Return returnvalue
  [ statements ]
End Operator

Как видно, переопределенный оператор должен быть Public и статическим (Shared). Он обязан принимать не менее одного и не более двух операндов, которые должны передаваться по значению (ByVal), и возвращает некоторое значение.

Условно операторы можно разделить на три группы: унарные – принимающие только один операнд, бинарные – принимающие два, и операторы преобразования. В качестве унарных операторов можно переопределять следующие:

Последние два оператора относятся к группе новых операторов языка. Давайте рассмотрим их более детально:

ПРИМЕЧАНИЕ

В C# операторы IsTrue и IsFalse не могут вызываться пользователем, однако в VB.NET такое ограничение отсутствует: функция называется op_True. Возможно, это недоработка Microsoft, которая исчезнет к выходу релиз-версии.

IsTrue и IsFalse предназначены для устранения конфликта приоритета операторов при использовании экземпляра типа, реализующего операторы Or и And (напомню, что Or и And в VB являются битовыми операторами) в конструкциях OrElse и AndAlso.

Их вызов происходит также, когда пользовательский класс используется в выражениях, требующих операнд типа Boolean, например, If, Do Loop, и т.п.

IsTrue и IsFalse должны реализовываться одновременно. Переопределенный пользовательский оператор обязан возвращать значение типа Boolean.

Если в классе реализованы операторы IsTrue, IsFalse, Or и And, то при использовании экземпляров этого класса в конструкции OrElse, логику работы можно описать примерно следующим псевдокодом:

        Dim t As <Type>
t = <first operand>
IfNot <Type>.op_True(t) Then
  t = <Type>.op_BitwiseOr(t, <second operand>)
EndIfIf <Type>.op_True(t) Then'инструкцияEndIf

Псевдокод для более, чем двух операндов несколько отличается, однако суть его остается той же. Как видно из кода, оптимизация заключается в многократном вызове переопределенного оператора IsTrue только одного операнда, который вернул True. Соответственно, этот оператор обязан быть константным, т.е. не изменять состояния объекта. К сожалению, в VB не существует (пока) средств для декларативного объявления константного метода, хотя потребность в этом возникает очень часто.

Оператор AndAlso можно выразить так:

        Dim t As <Type>
t = <first operand>
IfNot <Type>.op_False(t) Then
  t = <Type>.op_BitwiseAnd(t, <second operand>)
EndIfIf <Type>.op_True(t) Then'инструкцияEndIf

Пример переопределения логических, битовых операторов и оператора Not:

        Module Module1

  Sub Main()
    Dim _true AsNew cls(True), _false AsNew cls(False)
    If _true OrElse _false Then
      Console.WriteLine("ok")
    EndIfIfTrueOr _true Then
      Console.WriteLine("ok")
    EndIfIf _false OrElse _true Then
      Console.WriteLine("ok")
    EndIfIf _false AndAlso _true Then
      Console.WriteLine("ok")
    EndIf
    Console.WriteLine(Not _false)
  EndSubFriendClass cls
    Private _b AsBooleanPublicSubNew(ByVal b AsBoolean)
      _b = b
    EndSub'Битовый оператор OrPublicShared Operator Or(ByVal b AsBoolean, ByVal c As cls) AsBoolean
      Console.WriteLine("Or bool")
      Return c._b Or b
    End Operator
    'Оператор Or, необходимый для логического OrElsePublicShared Operator Or(ByVal b As cls, ByVal c As cls) As cls
      Console.WriteLine("Or cls")
      ReturnNew cls(c._b Or b._b)
    End Operator
    'Является ли класс истинойPublicShared Operator IsTrue(ByVal c As cls) AsBoolean
      Console.WriteLine("IsTrue: {0}", c._b)
      Return c._b
    End Operator
    'Оператор Or, необходимый для логического OrElsePublicShared Operator And(ByVal b As cls, ByVal c As cls) As cls
      Console.WriteLine("And cls")
      ReturnNew cls(c._b And b._b)
    End Operator
    'Является ли класс ложьюPublicShared Operator IsFalse(ByVal c As cls) AsBoolean
      Console.WriteLine("IsFalse: {0}", Not c._b)
      ReturnNot c._b
    End Operator
    'Оператор NotPublicShared Operator Not(ByVal c As cls) AsIntegerReturn 94
    End Operator
  EndClassEndModule

Данный пример выводит на экран следующее:

IsTrue: True
IsTrue: True
ok
IsTrue: False
Or cls
IsTrue: True
ok 
Or bool
ok
IsFalse: True
IsTrue: False
94

Выше уже приводились примеры бинарных операторов (Or и And). Вот оставшиеся операторы, которые могут быть переопределены: +, -, *, /, \, &, ^, >>, <<, =, <>, >, >=, <, <=, Like, Mod, и Xor.

Некоторые замечания и ограничения:

Последний тип операторов – операторы приведения типов. Фактически, это один оператор – CType, однако с его помощью можно переопределить любое явное и неявное преобразование.

Неявное преобразование достигается с помощью следующей конструкции:

        Public
        Shared Widening Operator CType(ByVal a As <SourceType>) As <TargetType>
End Operator

Например, преобразование нашего класса из Char и наоборот выглядит следующим образом:

        Public
        Shared Widening Operator CType(ByVal c AsChar) As cls
    ReturnNew cls(CBool(IIf(c = "t"c OrElse c = "T"c, True, False)))
  End Operator

  PublicShared Widening Operator CType(ByVal c As cls) AsCharReturnCChar(IIf(c._b, "T"c, "F"c))
  End Operator

Операторы явного преобразования выглядят так же, только вместо ключевого слова Widening используется Narrowing. Разница между ними состоит в том, что неявное преобразование вызывается компилятором автоматически, когда экземпляр типа используется в конструкции, требующих тип, к которому данный тип может быть неявно приведен. Явное преобразование требует обязательного указания операции преобразования типов (CType или его специализированные варианты наподобие CBool или CLng). Однако так компилятор будет поступать при условии, что опция Strict установлена в On. В противном случае компилятор будет вызывать операцию преобразования типов, определенную программистом, всегда, невзирая на то, явное это преобразование или нет. Для пары типов нельзя одновременно реализовать явное и неявное преобразование.

Лично у меня опция Strict всегда включена, так как это позволяет отлавливать большее количество ошибок во время компиляции.

Вот пример явного преобразования нашего типа в Integer и наоборот:

        Public
        Shared Narrowing Operator CType(ByVal c AsInteger) As cls
  ReturnNew cls(Convert.ToBoolean(c))
End Operator

PublicShared Narrowing Operator CType(ByVal c As cls) AsIntegerReturn Convert.ToInt32(c._b)
End Operator

Теперь его использование с включенной опцией Strict:

        Dim i AsInteger = _true 'Ошибка!Dim j AsInteger = CInt(_true) 'Правильно

На этом рассмотрение операторов можно завершить.

Новые типы

Наконец в Visual Basic появились беззнаковые типы и знаковый байт. Трудно сказать, насколько это хорошо, потому что язык потерял славу полностью CLS-совместимого языка. (Практически все расширения, которые появятся в .NET 1.2, не CLS-совместимы просто потому, что еще не принята новая версия стандарта. Де-факто же эти типы поддерживаются CLR с первой версии (а также Mono) в языках C# и MC++. Так что реально такое нововведение только увеличивает совместимость VB с другими языками .NET. – прим.ред.)

SByte хранит 8-битовое число в диапазоне от -128 до 127. Переменная этого типа может быть неявно преобразована к переменной типа Short, Integer, Long, Decimal, Single и Double. Для данного типа нет специального символьного литерала, для инициализации используется целый литерал соответствующего диапазона. Данному типу соответствует тип System.SByte.

UShort хранит 16-и битовое число в диапазоне от 0 до 65535. Переменная этого типа может быть неявно преобразована к переменной типа Integer, UInteger, Long, ULong, Decimal, Single и Double. Для данного типа нет специального символьного литерала, для инициализации используется целый литерал соответствующего диапазона. Данному типу соответствует тип System.UInt16.

UInteger хранит 32-x битовое число в диапазоне от 0 до 4,294,967,295. Переменная этого типа может быть неявно преобразована к переменной типа Long, ULong, Decimal, Single и Double. Для данного типа нет специального символьного литерала, для инициализации используется целый литерал соответствующего диапазона. Данному типу соответствует тип System.UInt32.

ULong хранит 64-x битовое число в диапазоне от 0 до 18,446,744,073,709,551,615. Переменная этого типа может быть неявно преобразована к переменной типа Decimal, Single и Double. Для данного типа нет специального символьного литерала, для инициализации испольуется целый литерал соответствующего диапазона. Данному типу соответствует тип System.UInt64.

Новые инструкции

Этот раздел наиболее интересен, так как описанные в нем нововведения ожидались больше всего.

Using

Наконец он появился! Его использование практически идентично использованию в C#. Например, следующие два куска кода порождают абсолютно одинаковый код:

C#
          using (IO.MemoryStream m1 = new IO.MemoryStream())
using (IO.MemoryStream m2 = new IO.MemoryStream())
{
}

или

IO.MemoryStream m1 = new IO.MemoryStream();
using (IO.MemoryStream m2 = m1)
{
}
VB.NET
          Using m1 AsNew IO.MemoryStream, m2 AsNew IO.MemoryStream
EndUsing

или

          Dim m1 AsNew IO.MemoryStream
Using m2 As IO.MemoryStream = m1
EndUsing

Continue

Второй раз ура! Согласитесь, это должно было появиться давно.

Инструкция Continue может использоваться во всех циклах, чтобы принудительно передать управление на начало цикла, т.е. когда нужно пропустить текущую итерацию и перейти к следующей. Например:

          'Подсчет суммы положительных элементов в массиве
          Dim arr() AsInteger = {10, -84, -4383, 193, 13}
    Dim sum AsInteger = 0
    ForEach i AsIntegerIn arr
        If i <= 0 ThenContinueFor
        sum += i
    Next

Различный уровень доступа для setter-ов и getter-ов

А вот это действительно ново (хотя и ожидаемо), потому что даже в C# реализовать подобное пока не удалось. Речь идет о различном уровне доступа для установки и чтения свойства (property). Свойства транслируются компилятором в набор методов set_<Имя свойства> и get_<Имя свойства>. Для этих методов устанавливается тот модификатор доступа, который был назначен свойству. Теперь у VB.NET-программистов появилась возможность назначать разный уровень доступа к процедурам считывания и установки свойств. Такая функциональность была доступна ранее только в MC++. Для примера напишем свойство получения и установления переменной для нашего класса:

          'get_Bool - открытый
          'set_Bool - открыт на уровне сборки
          Public
          Property Bool() AsBooleanGetReturn _b
        EndGetFriendSet(ByVal Value AsBoolean)
            _b = Value
        EndSetEndProperty

Модификатор доступа можно изменять только для одного из методов, для второго метода модификатор доступа задается на уровне свойства. Кроме этого, модификатор доступа не может быть «мягче» модификатора для всего свойства. Т.е. следующий код ошибочен:

          Private
          Property Bool() AsBooleanFriendGetReturn _b
        EndGetSet(ByVal Value AsBoolean)
            _b = Value
        EndSetEndProperty

Вот правильный вариант:

          Friend
          Property Bool() AsBooleanGetReturn _b
    EndGetPrivateSet(ByVal Value AsBoolean)
      _b = Value
    EndSetEndProperty

Частичные типы (partial types)

Частичные типы не являются расширением CLR и вообще не являются отдельным видом типов. Суть нововведения заключается в возможности расширять существующий класс в пределах одного проекта без использования наследования.

Допустим, в одном файле у вас создан класс SomeClass:

        Friend
        Class SomeClass
  PublicSub foo()
  EndSubEndClass

В другом файле вы можете расширить функциональность данного класса с помощью ключевого слова Expands следующим образом:

Expands Class SomeClass
  PublicSub bar()
  EndSubEndClass

Не ахти какая полезная возможность, однако многие инструментальные средства (и даже ASP.NET 2.0) используют ее.

ПРИМЕЧАНИЕ

Partial types, по замыслу Microsoft, являются средством разнесения одного типа на несколько физических файлов и предназначены для использования совместно с генераторами кода – чтобы отделить автоматически генерированный код от создаваемого программистом. – прим. ред.

На этом я заканчиваю рассмотрение расширений языка, которые не связаны с нововведениями CLR 1.2.

Нововведения CLR 1.2

Generics

Долгожданные шаблоны, наконец, появились, однако многих они могут разочаровать. Дело в том, что шаблоны в CLR 1.2 не являются сущностями времени компиляции. Это полноправные типы, к которым разрешен доступ во время исполнения программы. Как и другие типы, их можно создавать во время исполнения программы. С ними можно использовать средства отражения (reflection), например, обобщенные типы можно специализировать в рантайме:

        'Получаем тип обобщенного стека
        Dim GenericStackT As Type = Type.GetType("System.Collections.Generic.Stack")
If GenericStackT IsNot NothingThen'специализация стека для типа integerDim StackOfIntegerT As Type = GenericStackT.BindGenericParameters( _
    New Type() {GetType(Integer)})
  If StackOfIntegerT IsNot NothingThen'создание конкретного экземпляра стека для типа integerDim stack AsObject = StackOfIntegerT.InvokeMember(Nothing, _
      Reflection.BindingFlags.CreateInstance, Nothing, Nothing, Nothing)
    If stack IsNot NothingThen'просто демонстрация того, что все правильно
      Debug.Assert(stack.GetType().Equals( _
        GetType(Collections.Generic.Stack(Of Integer))))
    EndIfEndIfEndIf

Из этого примера уже можно понять, как использовать обобщенные типы в VB.NET: сразу после generic-типа необходимо в скобках после ключевого слова of написать через запятую типы-параметры шаблона.

Вот как выглядит словарь Integer-ов с ключом типа String:

        Dim d AsNew Collections.Generic.Dictionary(Of String, Integer)

Давайте рассмотрим, как конструировать свои собственные generic-типы.

Generic-классы

Вот как выглядит описание самого простого обобщенного типа:

        Friend
        Class GenericType(Of T)
        Public _t As T
    EndClass

Здесь переменная-член _t относится к типу-параметру T. К сожалению, ничего большего, чем простое объявление этой переменной, в generic-классе сделать нельзя. Например, невозможно создать экземпляр типа T, вызвать какой-либо его метод и т.д. Данное ограничение происходит от рантайм-природы generic-ов. Так как специализация может выполняться во время исполнения (как в предыдущем примере), вполне может случиться так, что тип, используемый в качестве аргумента, не будет иметь соответствующего конструктора, метода или оператора. В принципе, можно было бы в этот момент (т.е. в момент вызова BindGenericParameters) генерировать исключение, однако это противоречит самой идее generic-ов, так как при этом невозможно было бы обеспечить типобезопасность во время компиляции. Чтобы обеспечить проверку типов во время компиляции в отсутствие исходных кодов, разработчики решили ввести так называемые ограничения (constraints). К сожалению, ограничение на конкретный метод или оператор составить нельзя. В ограничениях можно указывать лишь интерфейс, класс или конструктор.

ПРИМЕЧАНИЕ

К очередному сожалению, в используемой мной версии компилятора невозможно указать в качестве ограничения конструктор. Однако разработчики уверяют, что эта ошибка исправлена в следующих версиях компилятора, которые пока недоступны публике.

Вот как выглядит generic-тип с ограничением на тип-параметр в виде интерфейса:

        Friend
        Class GenericType(Of T As ICloneable)
  Public _t As T
EndClass

Теперь переменную _t можно клонировать. Если необходимо указать несколько ограничений, необходимо использовать символ объединения &. Вот пример типа, который накладывает ограничение в виде класса и интерфейса:

        Friend
        Class GenericType(Of T As SomeClass & IDisposable)
  Public _t As T
EndClass

Круг операций, производимых над переменной _t, существенно расширился.

ПРИМЕЧАНИЕ

Кому-то этот синтаксис может показаться не слишком читабельным и логичным. Я соглашусь. Разработчики обещали, что в следующих версиях будет использоваться такая конструкция:

        Friend
        Class GenericType(Of T As {SomeClass, IDisposable})
  Public _t As T
EndClass
ПРИМЕЧАНИЕ

По крайней мере, это более наглядно.

Пока у нашего generic-класса был только один тип-параметр. Вот как задается второй:

        Friend
        Class GenericType(Of T1 As SomeClass & IDisposable, T2 AsObject)
  Public _t1 As T1
  Public _t2 As T2
EndClass

Для второго типа я указал ограничение на тип object, которое абсолютно ни о чем не говорит, т.е. при отсутствии какого-либо ограничения компилятор сам генерирует такой код.

Generic-методы

Кроме обобщенных классов, можно создавать generic-методы. Синтаксис фактически одинаков; вот пример genеric-метода с одним параметром:

        Friend
        Class SomeClass
  PublicSub foo(Of T)(ByVal _t As T)
    Console.WriteLine(_t)
  EndSubEndClass

Основное отличие обобщенных методов от классов состоит в том, что методы могут выводить типы своих параметров (как в С++). Например, предыдущий метод можно вызвать так:

c.foo(10)
c.foo(Of Integer)(10)

В первом случае компилятор сам вывел параметр шаблона по типу аргумента.

Вот как можно работать с обобщенным методом во время исполнения программы:

        Dim c AsNew SomeClass
Dim t As Type = GetType(SomeClass)
'Получаем информацию об обобщенном методе fooDim GenericMI As Reflection.MethodInfo = t.GetMethod("foo", _
  Reflection.BindingFlags.Instance Or Reflection.BindingFlags.Public)
'Метод foo действительно обобщенный?If GenericMI IsNot NothingAndAlso GenericMI.HasGenericArguments() Then'Выполняем специализацию для типа IntegerDim mi As Reflection.MethodInfo = _
    GenericMI.BindGenericParameters(New Type() {GetType(Integer)})
  If mi IsNot NothingThen'Вызов метода c.foo(10)
    mi.Invoke(c, Reflection.BindingFlags.Instance Or _
      Reflection.BindingFlags.Public, Nothing, _
      NewObject() {10}, Nothing)
  EndIfEndIf

Опять же ничего сложного.

Generic-делегаты

Если есть обобщенные методы, обобщенные указатели (т.е. generic-делегаты) не могут не появиться. Синтаксис все тот же. Вот пример делегата с одним аргументом:

        Delegate
        Sub SomeDelegate(Of T)(ByVal tt As T)

Об ограничениях (constraints) я говорить не буду, потому что все сказанное раньше справедливо и для generic-делегатов, лучше приведу пример использования. Далеко не пойдем: возьмем обобщенный метод foo из примера предыдущего раздела (конечно, для инициализации делегата можно использовать и простой, не обобщенный метод):

        Dim c AsNew SomeClass
Dim k As SomeDelegate(Of String) = AddressOf c.foo(Of String)
k("Hi from VB.NET!")

К сожалению, делегаты в VB.NET так до сих пор и не научились объединяться с использованием оператора +, поэтому вам по-прежнему нужно будет вызывать статический метод Combine. Возможно, в будущих версиях компилятора все изменится к лучшему.

Generic-операторы

Их нет, хотя не совсем понятно почему. Другая проблема с операторами заключается в том, что в моей версии компилятора их нельзя переопределять для обобщенных типов. Например, следующий код не компилируется с сообщением о том, что, по крайней мере, тип одного из параметров должен быть данного типа (т.е. GenericType(of T)):

        Friend
        Class GenericType(Of T AsObject)
  Public _t As T
  PublicShared Operator + (ByVal c As GenericType(Of T), ByVal i AsInteger) AsIntegerEnd Operator
EndClass

Как видите, тип первого параметра как раз GenericType(of T), однако компилятор думает по-другому. Надеюсь, ошибка будет исправлена.

Нововведения, которых пока нет :)

В этом разделе обсуждаются возможности, которые присутствуют в том же C#, но пока не появились в VB.NET. К ним относятся:

Другое

Документация

Теперь вы можете использовать xml-комментарии для автоматической генерации документации кода, как это всегда было в C#. VB.NET поддерживает практически все теги, используемые в C#. Программистам, не знакомым с этой возможностью, настоятельно рекомендую статью XML Comments Let You Build Documentation Directly From Your Visual Studio .NET Source Files из журнала MSDN Mag за июнь 2002 года.

Для генерации документации необходимо перед описываемой сущностью начать комментарий символом апострофа, а затем сразу же после него набрать символ @. Вот, например, как может выглядеть xml-документация для свойства с параметром:

        '@ <summary>
        '@ 
        '@ </summary>
        '@ <param name="p"></param>
        '@ <value></value>
        '@ <remarks></remarks>
        Public
        Property Prop(ByVal p AsInteger) AsStringGetEndGetSet(ByVal Value AsString)

            EndSetEndProperty

После компиляции проекта, в каталоге bin создается xml-документ, куда заносится все введенная вами информация.

ПРИМЕЧАНИЕ

Надо признаться, что пока все нововведения сделаны на весьма посредственном уровне. Так, например, не генерируется комментарий к частичному типу: видимо, среда не учитывает новое ключевое слово Expands.

Пространство имен My

Пространство имен My является таким же синтаксическим сахаром, как и анонимные методы в C#. Это, можно сказать, ответ команды разработчиков VB.NET команде C#.

Основное назначение пространства имен My заключается в упрощении доступа к основной функциональности FCL (Framework Class Library). Существенным ограничением является то, что это пространство доступно только в GUI-приложении (т.е. в проекте типа Windows Application).

Пространство имен My не только облегчает доступ к богатому набору классов FCL, но и предоставляет некоторую дополнительную функциональность. Например, с помощью класса Folder (My.Application.Folder) можно получить доступ к свойству Drive, которого нет у стандартного класса DirectoryInfo.

Пространство имен My можно разделить на шесть уровней:

Я не собираюсь подробно останавливаться на каждом из этих уровней, так как это справочная информация. Давайте лучше поговорим об использовании и реализации трех последних, на мой взгляд, самых интересных уровнях Forms, WebServices и DataSources.

Эти три уровня предоставляют доступ к именованным экземплярам форм, Web-сервисов и источников данных, соответственно. Что это значит? Это значит, что если вам нужен только один экземпляр формы или Web-сервиса, что наиболее вероятно, вам не нужно его создавать! Например, вы добавили в проект новую форму и хотите ее показать. Нет ничего проще!

        Private
        Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
  My.Forms.Form2.Show(Me)
EndSub

Никакого кода по созданию экземпляра второй формы нет, просто вызов метода Show. Примерно такая же ситуация обстоит с Web-сервисами:

        Private
        Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
  My.WebServices.<Имя вебсервиса>.<Метод вебсервиса>()
EndSub

Как все это волшебство работает? На все дает ответ ildasm.

Компилятор генерирует дополнительный класс под названием myvb_My. Это Private-класс, который наследуется от Microsoft.VisualBasic.WindowsPlatform.MyWindows и фактически является пространством имен My. Он определяет три вложенные класса: MyDataSources, MyForms и MyWebServices, доступ к экземплярам которых осуществляется с помощью свойств DataSources, Forms и WebServices. Эти три класса контролируют доступ к соответствующим именованным экземплярам.

Остальные уровни Application, Computer и User пространства имен My являются экземплярами типов Microsoft.VisualBasic.WindowsPlatform.Forms.App, Microsoft.VisualBasic.PC.Computer и Microsoft.VisualBasic.WindowsPlatform.User, соответственно. Они являются статическими, и компилятор практически не прикладывает руку к их использованию.

Все описанные выше типы являются пока недокументированными, однако можно сказать заранее с достаточно большой степенью уверенности, что они будут документированы в следующих версиях документации по .NET Framework.

Заключение

Вторая половина этого года обещает быть интересной: выход новой Visual Studio, нового Framework-а, новой версии MS SQL Server. Количество нововведений в них просто сумасшедшее, и, если не готовится к ним заранее, они застанут вас врасплох, как встреча с контролером при отсутствии проездного в кармане. Надеюсь, эта статья вооружила вас некоторыми техническими подробностями и подготовила морально к встрече с новыми продуктами Microsoft.


Эта статья опубликована в журнале RSDN Magazine #1-2004. Информацию о журнале можно найти здесь
    Сообщений 0    Оценка 240        Оценить