действия, которые поддерживаются типом object. Если же вы используете тип dynamic, то можете указать какое угодно действие, при условии что это действие поддерживается конкретным объектом, на который делается ссылка во время выполнения.

Для того чтобы стало понятно, насколько тип dynamic способен упростить решение некоторых задач, рассмотрим простой пример его применения вместе с рефлексией. Как пояснялось в главе 17, чтобы вызвать метод для объекта класса, получаемого во время выполнения с помощью рефлексии, можно, в частности, обратиться к методу Invoke (). И хотя такой способ оказывается вполне работоспособным, нужный метод намного удобнее вызвать по имени в тех случаях, когда его имя известно. Например, вполне возможна такая ситуация, когда в некоторой сборке содержится конкретный класс, поддерживающий методы, имена и действия которых заранее известны. Но поскольку эта сборка подвержена изменениям, то приходится постоянно убеждаться в том, что используется последняя ее версия. Для проверки текущей версии сборки можно, например, воспользоваться рефлексией, сконструировать объект искомого класса, а затем вызвать методы, определенные в этом классе. Теперь эти методы можно вызвать по имени с помощью типа dynamic, а не метода Invoke (), поскольку их имена известны.

Разместите сначала приведенный ниже код в файле с именем MyClass . cs. Этот код будет динамически загружаться посредством рефлексии.

public class DivBy {

public bool IsDivBy(int a, int b) { if ( (a % b) == 0) return true; return false;

}

public bool IsEven(int a) { if ( (a % 2) == 0) return true; return false;

}

}

Затем скомпилируйте этот файл в библиотеку DLL под именем MyClass .dll. Если вы пользуетесь компилятором командной строки, введите в командной строке следующее.

Далее составьте программу, в которой применяется библиотека MyClass . dll, как показано ниже.

// Использовать тип dynamic вместе с рефлексией.

using System;

using System.Reflection;

class DynRefDemo { static void Main() {

Assembly asm = Assembly.LoadFrom('MyClass.dll');

Type[] all = asm.GetTypes();

// Найти класс DivBy. int i;

for(i =0; i < all.Length; i++) if(all[i].Name == 'DivBy') break;

if(i == all.Length) {

Console.WriteLine('Класс DivBy не найден в сборке.'); return;

}

Type t = all[i];

//А теперь найти используемый по умолчанию конструктор.

Constructorlnfo[] ci = t.GetConstructors();

int j ;

for(j =0; j < ci.Length; j++)

if(ci[j].GetParameters().Length == 0) break;

if(j == ci.Length) {

Console.WriteLine('Используемый по умолчанию конструктор не найден.'); return;

}

I

// Создать объект класса DivBy динамически, dynamic obj = ci[j].Invoke(null);

// Далее вызвать по имени методы для переменной obj. Это вполне допустимо,

// поскольку переменная obj относится к типу dynamic, а вызовы методов // проверяются на соответствие типов во время выполнения, а не компиляции, if(obj.IsDivBy(15, 3))

Console.WriteLine('15 делится нацело на 3.'); else

Console.WriteLine('15 HE делится нацело на 3.');

if(obj.IsEven(9))

Console.WriteLine('9 четное число.'); else

Как видите, в данной программе сначала динамически загружается библиотека MyClass . dll, а затем используется рефлексия для построения объекта класса DivBy. Построенный объект присваивается далее переменной obj типа dynamic. А раз так, то методы Is DivBy () и IsEven () могут быть вызваны для переменной obj по имени, а не с помощью метода Invoke (). В данном примере это вполне допустимо,

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату