Как правильно бросить объекты, созданные посредством отражения

Очень простой пример вариационного шаблона:

Предположим, мы хотим иметь функцию, которая принимает переменное количество аргументов и печатает их все. Для 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;}

и так далее ...

Любое из них будет работать. Надеюсь, это поможет вам в следующий раз, когда вы начнете писать такую ​​функцию или класс.

10
задан Ben Robbins 28 August 2008 в 03:12
поделиться

6 ответов

Я просто предполагаю здесь, потому что из Вашего кода не очевидно, где у Вас есть определение интерфейса IPlugin, но если Вы не можете бросить в своем хост-приложении затем, у Вас, вероятно, есть интерфейс IPlugin в Вашем блоке хоста и затем одновременно в Вашем сменном блоке. Это не будет работать.

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

4
ответ дан 4 December 2019 в 02:27
поделиться

хм... Если Вы используете блок. LoadFrom для загрузки блока пытаются изменить его блок. LoadFile вместо этого.

Работавший для меня

Отсюда: http://www.eggheadcafe.com/community/aspnet/2/10036776/solution-found.aspx

2
ответ дан 4 December 2019 в 02:27
поделиться

@lubos hasko

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

Я попробовал разное решение реализацией хостов и интерфейсным блоком и сменным блоком реализации. В том решении код в первом блоке работал как ожидалось.

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

1
ответ дан 4 December 2019 в 02:27
поделиться

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

Activator.CreateInstance(type, true);

Кроме того, в Вашем первом примере посмотрите, является ли o пустым, и в противном случае распечатайте o. GetType ().Name для наблюдения, каково это действительно.

0
ответ дан 4 December 2019 в 02:27
поделиться

@Haacked

Я пытался сохранить псевдокод простым. foreach's поднимает много пространства и фигурных скобок. Я разъяснил его.

o. GetType ().FullName возвращает Плагины. Умножьтесь, который является ожидаемым объектом. Плагины. Умножьте реализации IPlugin. Я ступил посредством процесса в отладчик довольно много раз, пока я не сдался в течение вечера. Не мог выяснить, почему я не мог бросить его, потому что я наблюдал, что конструктор стрелял, пока я не стал сварливым о целой путанице. Возвратился к нему этим вечером и заставил его работать, но я все еще не понимаю, почему состав исполнителей перестал работать в первом блоке кода. Вторые работы блока кода, но это чувствует прочь мне.

0
ответ дан 4 December 2019 в 02:27
поделиться

Я просто пытался работать это сам и сумел наткнуться на ответ!

У меня было 3 различных проекта C#

  • A - Сменный Интерфейсный проект
  • B - Разместите exe проект-> ссылки A
  • C - Сменный Проект внедрения-> ссылки A

Я получал ошибку кастинга также, пока я не изменил имя сборки для своего Сменного Интерфейса proj для соответствия пространству имен того, к чему я пытался бросить.

Например.

IPluginModule pluginModule = (IPluginModule)Activator.CreateInstance(curType);

перестал работать, потому что блок, в котором был определен интерфейс IPluginModule, назвали 'Распространенным', - типом, к которому я бросал, был 'Вздор. Плагины. Распространенный. IPluginModule' как бы то ни было.

Я изменил Имя сборки для интерфейса proj, чтобы быть 'Вздором. Плагины. Распространенный' означал что бросок, за которым затем следуют.

Надо надеяться, это объяснение помогает кому-то. Назад к коду..

1
ответ дан 4 December 2019 в 02:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: