Студопедия
rus | ua | other

Home Random lecture






Исполняющая среда динамических языков


Date: 2015-10-07; view: 374.


Хотя с технической точки зрения Visual Basic в своей основе является статическим языком, в нем всегда были очень мощные динамические средства, например позднее связывание (late binding). Visual Studio 2010 поставляется с новой платформой под названием Dynamic Language Runtime (DLR), которая упрощает создание динамических языков и взаимодействие между ними. Visual Basic 2010 полностью поддерживает DLR, позволяя использовать библиотеки и инфраструктуры, написанные на таких языках, как Iron­Python и IronRuby.

Самое интересное, что эта поддержка не потребовала никаких изменений в синтаксисе (фактически в компиляторе не было модифицировано ни одной строки кода). Разработчики могут по-прежнему, как и в предыдущих версиях Visual Basic, определять операции с поздним связыванием. Изменения внесены в исполняющую среду Visual Basic Runtime (Microsoft.Visual­Basic.dll), которая теперь распознает интерфейс IDynamicMetaObjectProvider, предоставляемый DLR. Если объект реализует этот интерфейс, Visual Basic Runtime сконструирует DLR CallSite и позволит этому объекту и предоставляющему его языку object ввести в операцию собственную семантику.

Например, стандартные библиотеки Python (Python Standard Libraries) содержат файл random.py с методом shuffle, который можно использовать для случайного переупорядочения элементов в массиве. Вызвать его несложно:

Dim python As ScriptRuntime = Python.CreateRuntime()

Dim random As Object = python.UseFile("random.py")

 

Dim items = {1, 2, 3, 4, 5, 6, 7}

random.shuffle(items)

В период выполнения Visual Basic обнаруживает, что объект реализует IDynamicMeta­ObjectProvider, и передает управление DLR, которая взаимодействует с Python и выполняет метод (передавая массив, определенный в Visual Basic как аргумент метода).

Это пример вызова API с поддержкой DLR, но разработчики могут создавать свои API, использующие DLR. Самое главное при этом — реализовать интерфейс IDynamicMetaObjectProvider, и тогда компиляторы Visual Basic и C# увидят, что объект имеет особую динамическую семантику. Вместо реализации интерфейса вручную проще наследовать от класса System.­Dynamic.DynamicObject (который уже реализует этот интерфейс) и переопределить пару методов. На рис. 3 показан полный пример создания собственного динамического объекта и его вызова с использованием обычного для Visual Basic механизма позднего связывания.

Рис.3 Создание собственного динамического объекта и его вызов из Visual Basic через механизм позднего связывания

Imports System.Dynamic

Module Module1

Sub Main()

Dim p As Object = New PropertyBag

p.One = 1

p.Two = 2

p.Three = 3

Console.WriteLine(p.One)

Console.WriteLine(p.Two)

Console.WriteLine(p.Three)

End Sub

Class PropertyBag : Inherits DynamicObject

Private values As New Dictionary(Of String, Integer)

Public Overrides Function TrySetMember(

ByVal binder As SetMemberBinder,

ByVal value As Object) As Boolean

values(binder.Name) = value

Return True

End Function

Public Overrides Function TryGetMember(

ByVal binder As GetMemberBinder,

ByRef result As Object) As Boolean

Return values.TryGetValue(binder.Name, result)

End Function

End Class

End Module

Обобщенная вариантность

Эта функциональность, название которой поначалу кажется весьма заумным (с ее терминами «ковариантность» и «контравариантность»), на самом деле довольно проста. Если у вас есть объект типа IEnumerable(Of Apple) и вы хотите присвоить его IEnumerable(Of Fruit), то эта операция должна быть допустимой, так как каждый объект Apple (яблоко) наследует от Fruit (фрукт). Увы, до Visual Basic 2010 обобщенная вариантность не поддерживалась компилятором, хотя общеязыковая исполняющая среда (Common Language Runtime, CLR) полностью поддерживала такую возможность.

Рис.4 Пример обобщенной вариантности

Option Strict On

Public Class Form1

Sub Form1_Load() Handles MyBase.Load

Dim buttons As New List(Of Button) From

{

New Button With

{

.Name = "btnOk",

.Enabled = True

},

New Button With

{

.Name = "btnCancel",

.Enabled = False

}

}

 

Dim enabledOnly = FilterEnabledOnly(buttons)

End Sub

Function FilterEnabledOnly(

ByVal controls As IEnumerable(Of Control)

) As IEnumerable(Of Control)

Return From c In controls

Where c.Enabled = True

End Function

End Class

Самое большое преимущество обобщенной вариантности — об этой функциональности не нужно беспокоиться самому:если она выполняет свою работу, вы никогда этого не заметите. Ситуации, в которых раньше возникали ошибки компиляции или требовался вызов .Cast(Of T), не должны создавать проблем в Visual Basic 2010.


<== previous lecture | next lecture ==>
Литералы массивов | Ориентация на несколько версий инфраструктуры
lektsiopedia.org - 2013 год. | Page generation: 0.041 s.