Invoke MethodBase Invoke on the constructor (reflection)

First of all, sorry if this was asked before. I did a fairly comprehensive search and did not find anything, but maybe I missed something.

And now to the question: I'm trying to call the constructor through reflection, without luck. Basically, I have an object that I want to clone, so I'm looking for a copy constructor for its type, and then I want to call it. Here is what I have:

public Object clone(Object toClone) {
     MethodBase copyConstructor = type.GetConstructor(
         new Type[] { toClone.GetType() });
     return method.Invoke(toClone, new object[] { toClone }); //<-- doesn't work
}

I call the above method as follows:

List<int> list = new List<int>(new int[] { 0, 1, 2 });
List<int> clone = (List<int>) clone(list);

Now notice that the invoke method that I use invokes MethodBaseinvoke. ConstructorInfoprovides an invoke method that works if called as follows:

return ((ConstructorInfo) method).Invoke(new object[] { toClone });

MethodBase, , , , , Dictionary<MethodBase>, Dictionary<ConstructorInfo>. , , ConstructorInfo, , MethodBase . .

? .




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 invoke , . , , , , Invoke ConstructorInfo MethodBase invoke, , , . , Func<,> , . Clone , , .

Func<,>, -, ( - ), . , , !:)

+3
1

, , 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;
    }
}
+4

Source: https://habr.com/ru/post/1739113/


All Articles