首先,对不起,如果以前问过。我已经进行了非常全面的搜索,但没有发现类似的搜索,但是我可能错过了一些东西。

现在是一个问题:我试图通过反射调用构造函数,没有运气。基本上,我有一个要克隆的对象,因此我查找复制构造函数的类型,然后想调用它。这是我所拥有的:

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;
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top