Очень простой пример вариационного шаблона:
Предположим, мы хотим иметь функцию, которая принимает переменное количество аргументов и печатает их все. Для ex:
print("Hello", 1, 3.14, 5L);
Для этой функциональности нам потребовались бы в основном две функции:
Первая, функция, которая принимает переменное число аргументов:
template<typename T, typename... Args>
void print(T t, Args ...args){
std::cout << t << ", ";
print(args...);
}
Некоторые объяснения:
1.) Пакеты параметров, обозначенные ellipsis (...), которые отображаются в списке параметров.
typename...Args
| | << Optional whitespace. Can have multiple whitespaces in between them
Args...args
Это означает, что все они одинаковы .
typename ...args
typename...args
typename ... args
Итак, вам не нужно беспокоиться о правильной позиции пробелов. Хотя в качестве наилучшей практики следует использовать ИМО не более одного пробела.
2.) Расширение пакета: шаблон, за которым следует многоточие.
print(args...); //expand when you wish to use them
3.) Пакет параметров принимает нулевые или более шаблонные аргументы. Таким образом, print(T t, Args... args)
принимает один или несколько аргументов .
Как только вы это понимаете, мы можем визуализировать поток вызовов, как показано ниже:
print("Hello", 1, 3.14, 5L);
означает:
print(string, int, float, long);
, который вызывает
print(int, float, long);
, который вызывает
print(float, long); // say Level 2
, который вызывает
print(long); // say Level 1
, который вызывает
print(); // say Level 0
Если вы внимательно следили за точкой № 3, вы должны были понять, что print(T t, Args... args)
не может обрабатывать вызов на уровне 0. Поэтому нам нужна другая функция здесь с тем же именем догоняйте на любом уровне> = 0.
Во-вторых, функция захватывает вызов в верхней части стека вызовов:
Catch на уровне 0:
void print(){}
или, Поймать на уровне 1:
template<typename T>
void print(T t){ std::cout << t;}
или, Поймать на уровне 2:
template<typename T, typename U>
void print(T t, U u){ std::cout << t << ", " << u;}
и так далее ...
Любое из них будет работать. Надеюсь, это поможет вам в следующий раз, когда вы начнете писать такую функцию или класс.
Я просто предполагаю здесь, потому что из Вашего кода не очевидно, где у Вас есть определение интерфейса IPlugin, но если Вы не можете бросить в своем хост-приложении затем, у Вас, вероятно, есть интерфейс IPlugin в Вашем блоке хоста и затем одновременно в Вашем сменном блоке. Это не будет работать.
Самая легкая вещь состоит в том, чтобы сделать эту работу, должен был отметить интерфейс IPlugin как общественность в Вашем блоке хоста и затем иметь Ваш Сменный блок хост-приложения ссылки на сборку, таким образом, оба блока имеют доступ к тому же самому интерфейсу.
хм... Если Вы используете блок. LoadFrom для загрузки блока пытаются изменить его блок. LoadFile вместо этого.
Работавший для меня
Отсюда: http://www.eggheadcafe.com/community/aspnet/2/10036776/solution-found.aspx
Вы закрепили его на носу. Мой первоначальный проект действительно имел три различных блока и с хостом и со сменной реализацией, ссылающейся на сменный интерфейсный блок.
Я попробовал разное решение реализацией хостов и интерфейсным блоком и сменным блоком реализации. В том решении код в первом блоке работал как ожидалось.
Вы дали мне немного больше для размышления о, потому что я не совсем понимаю, почему два блока, ссылающиеся на общий блок, не вытаскивают тот же тип из общего блока.
Ваш тип, не общедоступный, если так, назовите перегрузку, которая берет в булевской переменной:
Activator.CreateInstance(type, true);
Кроме того, в Вашем первом примере посмотрите, является ли o пустым, и в противном случае распечатайте o. GetType ().Name для наблюдения, каково это действительно.
Я пытался сохранить псевдокод простым. foreach's поднимает много пространства и фигурных скобок. Я разъяснил его.
o. GetType ().FullName возвращает Плагины. Умножьтесь, который является ожидаемым объектом. Плагины. Умножьте реализации IPlugin. Я ступил посредством процесса в отладчик довольно много раз, пока я не сдался в течение вечера. Не мог выяснить, почему я не мог бросить его, потому что я наблюдал, что конструктор стрелял, пока я не стал сварливым о целой путанице. Возвратился к нему этим вечером и заставил его работать, но я все еще не понимаю, почему состав исполнителей перестал работать в первом блоке кода. Вторые работы блока кода, но это чувствует прочь мне.
Я просто пытался работать это сам и сумел наткнуться на ответ!
У меня было 3 различных проекта C#
Я получал ошибку кастинга также, пока я не изменил имя сборки для своего Сменного Интерфейса proj для соответствия пространству имен того, к чему я пытался бросить.
Например.
IPluginModule pluginModule = (IPluginModule)Activator.CreateInstance(curType);
перестал работать, потому что блок, в котором был определен интерфейс IPluginModule, назвали 'Распространенным', - типом, к которому я бросал, был 'Вздор. Плагины. Распространенный. IPluginModule' как бы то ни было.
Я изменил Имя сборки для интерфейса proj, чтобы быть 'Вздором. Плагины. Распространенный' означал что бросок, за которым затем следуют.
Надо надеяться, это объяснение помогает кому-то. Назад к коду..