Попытка использовать Activator.CreateInstance (MyType) - PullRequest
0 голосов
/ 25 мая 2011

У меня следующая проблема:

public class MyType
{
    public void method(int a, params object[] p){} 
    public void MyType()
    {
        method(5);
    }
}

Когда я использую конструктор, все хорошо, но когда я пытаюсь использовать Activator.CreateInstance(MyType);

void Factory()
{
    string componentPath = "MyType.dll";
    Assembly component = Assembly.LoadFrom(componentPath);
    Type myType= component.GetType("MyType");
    Activator.CreateInstance(myType);
}

происходит сбой, исключение MyType.method(int32) не найдено. Важно отметить, что до того, как я добавил params object[] p в метод, все работало нормально.

Спасибо.

Ответы [ 2 ]

3 голосов
/ 25 мая 2011

Если вы используете методы с необязательными параметрами или методы с params для передачи переменного числа параметров, то вы говорите компилятору, что когда вы CALL этот метод, он вставит необходимые параметры для вас? Необязательные параметры и массивы параметров вставляются в вызывающий код, а не в вызываемый код. (см. одно из сообщений Эрика Липперта в блоге о необязательных параметрах для уточнения).

Вы не используете компилятор C #, и Reflection API не вставляет эти параметры для вас. Например, вы можете проверить это не только с помощью отражения, но и с помощью двух сборок: Сборка A объявляет method(int X); это компилируется, и dll ссылается на сборку B. Эта сборка B содержит вызов method(42). Это отлично работает! Теперь, если вы перекомпилируете сборку A и измените подпись на method(int X, object bla=null) или method(int X, params object[] blas), тогда сборка B перестанет работать - она ​​содержит неверный вызов. Несмотря на это, исходный код сборки B все еще в порядке - вам просто нужно перекомпилировать.

Отражение просто не делает никакой дополнительной опции волшебства для вас. Это может , конечно - но это не так. Хотя отражение не поддерживает это, DLR делает, что приводит меня к следующему ...

Обходной путь: Попробуйте по возможности использовать ключевое слово C # dynamic, если это возможно (для конструкторов, это не AFAIK), которое пытается эмулировать соглашения о вызовах C # более тесно и поддерживает такие вещи, как необязательные и именованные параметры. Возможно, вам придется изменить способ настройки вашего API, однако использовать методы, а не конструкторы. Трудно дать более точный совет, не видя реального кода.

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

(Примечание: ваш пример кода неполон - я делаю небольшую догадку, что method на самом деле конструктор, но вы действительно должны опубликовать реальный код или хотя бы фрагмент, который на самом деле не работает).

0 голосов
/ 25 мая 2011

Это не сработает, потому что вам нужно передать как минимум 2 параметра при вызове метода (). Модификатор params не означает «необязательный».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...