11 березня 2010 р.

DLR in .Net

DLR(Dynamic Language Runtime) – одна из новых фич .Net 4.0. DLR используется для того чтоб можно было взаимодействовать с динамическими языками, такими как IronRuby & IronPython. Также с помощью DLR программисты могут создавать свои динамические языки, создавать динамические объекты, и ещё много всяких вкусностей про которые мы сегодня и поговорим.
Что входит в DLR для .Нет 4.0:



Expression Trees (деревья выражений):
Деревья выражений представляют языковый код в виде данных. Данные хранятся в древовидной структуре. Каждый узел в дереве выражений представляет выражение, например вызов метода или двоичную операцию, такую как x < y.( msdn )

// Add the following using directive to your code file:
// using System.Linq.Expressions;
// Create an expression tree.
Expression> exprTree = num => num < 5;
// Decompose the expression tree.
ParameterExpression param = (ParameterExpression)exprTree.Parameters[0];
BinaryExpression operation = (BinaryExpression)exprTree.Body;
ParameterExpression left = (ParameterExpression)operation.Left;
ConstantExpression right = (ConstantExpression)operation.Right;
Console.WriteLine("Decomposed expression: {0} => {1} {2} {3}",
param.Name, left.Name, operation.NodeType, right.Value);
/* This code produces the following output:
Decomposed expression: num => num LessThan 5
*/

Call Site Caching
Допустим у вас есть 2 данимических объекта a и b. Возможно, будет очень много мест в коде , где вы будете поризводить операции над этими объектами, допустим сложение. Операция над динамическими объектами – медленная операция, потом программисты Microsoft решили эту проблему кэшем. Call Site Cashing –кэширует харахтеристики ваших динамических объектов, и если операция вызывается повторно – не выполняет это операция опять, а просто возвращает данные из кэша.

Динамические объекты.
В .Нете 4.0 нам представлен новый тип переменной – динамическая переменная (dynamic ). Использование этой переменной заставляет компилятор решать какой тип переменной использовать в рантайме.

К примеру такой код , не выдаст нам ошибки на этапе компиляции, но выдаст 2 ошибки в рантайме:

public class TestClass
{ }
class Program
{
static void Main(string[] args)
{
dynamic dynObject = new TestClass();
string testString = dynObject.Hello();//error 1
dynamic dynObject2 = 7.0;
int i = dynObject2;//error 2
}
}

Но давайте же сдеаем несколько модификаций, чтоб эти ошибки пропали. Для создания динамических объектов, в .Нет 4.0 мы можем наследовать наши объекты от DynamicObject класса который содержит в себе большое количество виртуальных методов, с помощью которых мы можем граммотно рганизовать выполнение всякого рода динамических методов, свойств, и т.д.
К примеру, вот такой код, выполнится и запустится без проблем:

public class TestClass :DynamicObject
{
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
if (binder.Name == "Hello")
{
result = "This is Dynamic Object";
return true;
}
return base.TryInvokeMember(binder, args, out result);
}
}

class Program
{
static void Main(string[] args)
{
dynamic dynObject = new TestClass();
string testString = dynObject.Hello();
dynamic dynObject2 = 7.0;
int i = (int)dynObject2;
}
}


Но, ничего бы из этого не было возможным, если бы не ExpandoObject.
ExpandoObject – это новый и странный зверь в .Нете 4.0 который позволяет нам в рантайме добавлять новые свойства и методы. Следующим куском коды, мы создаем объект и в коде добавляем к нему два новых свойства и метод:

static void Main(string[] args)
{
dynamic MyExpando = new ExpandoObject();
MyExpando.Value1 = "new value 1";
MyExpando.Value2 = "new value 2";
MyExpando.DoSomething = new Action(() => Console.WriteLine("DoSomething called"));
Console.WriteLine(MyExpando.Value1);
MyExpando.DoSomething();
}


Что ж, подобьем итоги.
Где можно использовать динамические объекты:
  • Чтобы взаимодействовать объекты из динамических языков, таких как IronRuby и IronPython.
  • Для взаимодействия с COM объектами
  • Как замена рефлекции.
  • Для объектов, структра которых может меняться( HTML, XML, etc);

Плюсы:
  • Очень гибкие аппликации.
  • Краткость и понятность кода.

Минусы:
  • Уменьшение производительности.
  • Поетнциальная опасность возникновения ошибок в рантайме.



Немає коментарів:

Дописати коментар