调用Methodbase对构造函数的调用(反射)
-
23-09-2019 - |
题
首先,对不起,如果以前问过。我已经进行了非常全面的搜索,但没有发现类似的搜索,但是我可能错过了一些东西。
现在是一个问题:我试图通过反射调用构造函数,没有运气。基本上,我有一个要克隆的对象,因此我查找复制构造函数的类型,然后想调用它。这是我所拥有的:
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);
现在,请注意我正在使用的调用方法是 MethodBase
'调用。 ConstructorInfo
提供了一种调用方法,如果这样调用,则确实有效:
return ((ConstructorInfo) method).Invoke(new object[] { toClone });
但是,我想使用 MethodBase
的方法,因为实际上,每当我将其存储在字典中,而词典都包含方法和构造函数时,而不是查找复制构造函数,所以这是一个 Dictionary<MethodBase>
, , 不是 Dictionary<ConstructorInfo>
。我当然可以铸造 ConstructorInfo
就像我上面做的那样,但我宁愿避免铸造并使用 MethodBase
方法直接。我只是无法弄清楚正确的参数。
有帮助吗?非常感谢。
编辑
本杰明,
非常感谢您的建议。我实际上是在做您在第二次编辑中的建议,除了(这是一个很大的“除了”)我的词典在哪里
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
' invoke
关于我在词典中发现的内容。我没有添加所有这些代码 ConstructorInfo
使用 MethodBase
' Invoke
方法,所以我不想添加不必要的信息和太多代码供你们阅读。但是,我喜欢你的使用 Func<,>
好多多了,所以我要切换到这一点。也制作 Clone
方法通用是一个不错的补充,但是在我的情况下,呼叫者不知道该对象的类型,因此我将其保留为非生成。
我不知道 Func<,>
, ,如果我知道我已经忘记的lambda操作员(我以前真的不需要这样的事情),所以我实际上从您的答案中学到了很多东西。我一直喜欢学习新事物,这将来会很方便,所以非常感谢! :)
解决方案
如果您知道该对象具有这样的构造函数,您是否考虑过使用这种超载 Activator.CreateInstance
反而?
更新:因此,您已经对MethodInfo/Methodbase进行了级联搜索,并存储它们 - >您不需要/不能使用 Activator
.
在这种情况下,我看不到没有演员的方法。但是 - 也许您可以更改架构以存储一个 Dictionary<Type, Func<object, object>>
并添加那些 Func<>
相反,实例。使通话代码更加好(我假设),并允许您进行一次铸造:
// Constructor
dictionary.Add(type,
source => ((ConstructorInfo) method).Invoke(new object[] {source})
);
// Clone
dictionary.Add(type,
source => method.Invoke(source, new object[]{})
);
实际上,由于您只关心抓取它们的网站上的构造函数和普通方法之间的差异,因此您根本不需要演员表,对吗?
// Constructor 2
dictionary.Add(type,
source => yourConstructorInfo.Invoke(new object[] {source})
);
除非我缺少某些东西(当然很可能),这可能会通过在栅栏的定义一侧进行一次解决问题,而呼叫者不需要介意这是否是构造函数?
最后一次,我将停止编辑垃圾邮件。我很无聊,并提出了以下代码。那是您要完成的工作吗?
public class Cloner {
private readonly IDictionary<Type, Func<object, object>> _cloneMap =
new Dictionary<Type, Func<object, object>>();
public T Clone<T>(T source) {
Type sourceType = source.GetType();
Func<object, object> cloneFunc;
if (_cloneMap.TryGetValue(sourceType, out cloneFunc)) {
return (T)cloneFunc(source);
}
if (TryGetCopyConstructorCloneFunc(sourceType, out cloneFunc)) {
_cloneMap.Add(sourceType, cloneFunc);
return (T)cloneFunc(source);
}
if (TryGetICloneableCloneFunc(sourceType, out cloneFunc)) {
_cloneMap.Add(sourceType, cloneFunc);
return (T)cloneFunc(source);
}
return default(T);
}
private bool TryGetCopyConstructorCloneFunc(Type type,
out Func<object, object> cloneFunc) {
var constructor = type.GetConstructor(new[] { type });
if (constructor == null) {
cloneFunc = source => null;
return false;
}
cloneFunc = source => constructor.Invoke(new[] { source });
return true;
}
private bool TryGetICloneableCloneFunc(Type type,
out Func<object, object> cloneFunc) {
bool isICloneable = typeof(ICloneable).IsAssignableFrom(type);
var cloneMethod = type.GetMethod("Clone", new Type[] { });
if (!isICloneable || (cloneMethod == null)) {
cloneFunc = source => null;
return false;
}
cloneFunc = source => cloneMethod.Invoke(source, new object[] {});
return true;
}
}