C #: Func with inherited type constructor

As we know, you can point to the constructor as Func<T>follows:

Func<MyObject> constructor = () => new MyObject();
var newObject = constructor();

But is there a way to make a constructor for an object that, as you know, inherits from MyObject , but you don’t know its exact type?

Type inheritedObjectType = obj; // Parameter
Func<MyObject> constructor = () => new MyObject(); // as inheritedObjectType
var newInheritedObject = constructor; // Should now be of the inherited type

An answer using Activatoror anything returning Objectis not an option.

Change . I do not know what type of derived type is at compile time. I have only System.Type.

+3
source share
2 answers

You can use expression trees to build and compile a delegate that will create your derived type:

Func<TBase> CreateDelegate<TBase>(Type derived)
{
    var ctor = derived.GetConstructor(Type.EmptyTypes);

    if (ctor == null)
    {
        throw new ArgumentException("D'oh! No default ctor.");
    }

    var newExpression = Expression.Lambda<Func<TBase>>(
        Expression.New(ctor, new Expression[0]), 
        new ParameterExpression[0]);

    return newExpression.Compile();
}

:

Func<MyBase> create = CreateDelegate<MyBase>(typeof(Derived));

MyBase instance = create();

, .

+7

?

class MyObject{}
class Derived : MyObject {}
internal class Program
{

    public static void Main()
    {
        // the type you want to construct
        Type type = typeof (Derived);

        MethodInfo getConstructor = MakeConstructorGetter(type);
        Func<MyObject> constructor = (Func<MyObject>)getConstructor.Invoke(null, null);

        var obj = constructor();
        Console.WriteLine(obj.GetType());
    }

    private static MethodInfo MakeConstructorGetter(Type type)
    {
        MethodInfo mi = typeof(Program).GetMethod("GetObjectConstructor", BindingFlags.Static | BindingFlags.NonPublic);
        var getConstructor = mi.MakeGenericMethod(type);
        return getConstructor;
    }

    private static Func<T> GetObjectConstructor<T>() where T : MyObject, new()
    {
        return () => new T();
    }
}

MakeConstructorGetter , , Type, . , , , , , .

+2

All Articles