Прежде всего, извините, если это было задано раньше. Я сделал довольно полный поиск и не нашел ничего подобного, но я, возможно, что-то пропустил.Вызов методаBase's Invoke на конструкторе (отражение)
А теперь на вопрос: Я пытаюсь вызвать конструктора через отражение, без везения. В принципе, у меня есть объект, который я хочу клонировать, поэтому я ищу конструктор копирования для его типа, а затем хочу вызвать его. Вот что у меня есть:
public Object clone(Object toClone) {
MethodBase copyConstructor = type.GetConstructor(
new Type[] { toClone.GetType() });
return method.Invoke(toClone, new object[] { toClone }); //<-- doesn't work
}
Я называю вышеупомянутый метод следующим образом:
List<int> list = new List<int>(new int[] { 0, 1, 2 });
List<int> clone = (List<int>) clone(list);
Теперь обратите внимание на метод Invoke я использую MethodBase
«s Invoke. ConstructorInfo
предоставляет метод Invoke, который делает работу, если вызывается так:
return ((ConstructorInfo) method).Invoke(new object[] { toClone });
Однако я хочу использовать метод MethodBase
«s, потому что в действительности вместо того, чтобы искать конструктор копирования каждый раз, когда я буду хранить его в словаре , а словарь содержит как методы, так и конструкторы, поэтому это Dictionary<MethodBase>
, а не Dictionary<ConstructorInfo>
. Я мог бы, конечно, бросить на ConstructorInfo
, как я выше, но я бы предпочел избежать литья и использовать метод MethodBase
напрямую. Я просто не могу понять правильные параметры.
Любая помощь? Спасибо.
EDIT
Benjamin,
спасибо за ваши предложения. Я был на самом деле делает именно то, что вы предлагаете в вашем втором редактировать, за исключением (и это большой «кроме») мой словарь был где
class ClonerMethod {
public MethodBase method;
public bool isConstructor;
...
public Object invoke(Object toClone) {
return isConstructor ?
((ConstructorInfo) method).Invoke(new object[] { toClone }) : //<-- I wanted to avoid this cast
method.Invoke(toClone, null);
}
}
И тогда я назвал ClonerMethod
«s invoke
на то, что я нашел в словаре. Я не добавлял код ко всем сделкам, потому что ответ, который я искал, - это просто вызов Invoke на ConstructorInfo
с использованием метода MethodBase
MethodBase
, поэтому я не хотел добавлять лишнюю информацию и слишком много кода для вы, ребята, читаете. Однако мне очень нравится использование Func<,>
, поэтому я перехожу к этому. Кроме того, создание общего метода Clone
является хорошим дополнением, но в моем случае вызывающий не знает тип объекта, поэтому вместо этого я сохраню его не общее.
Я не знал о Func<,>
, и, если бы знал об операторе лямбды, я забыл (мне раньше не нужно было что-то подобное), поэтому я действительно многому научился от вашего ответа. Я всегда люблю изучать новые вещи, и это пригодится в будущем, поэтому большое спасибо! :)
Вы должны использовать метод, чтобы вызвать правильный метод. Это никогда не должно быть проблемой, вы будете обрабатывать возвращаемое значение по-разному, когда вы вызываете конструктор. –
@nobugz: см. Обновления OP ниже моего ответа. Кажется, идея (и проблема с реализацией указанной идеи) заключается в том, чтобы хранить способы клонирования объекта, которые могут быть методами ('ICloneable.Clone') или конструкторы (конструктор копирования, выше). Вызывающий код не должен заботиться, если я получу его сейчас, и OP trie [sd], чтобы найти способ одинаково обрабатывать оба способа, как 'MethodBase.Invoke()'. –
Хорошо, тогда оператор * is * будет работать нормально, чтобы обнаружить, что это фактически ConstructorInfo. –