mardi 11 septembre 2018

How can I use Activator.CreateInstance to create a List

I'm using Activator.CreateInstance to create objects by a type variable (unknown during run time):

static dynamic CreateFoo( Type t ) =>
    Activator.CreateInstance( t );

Obviously, I do not yet properly understand how to use the dynamic type, because this is still just returning an object.

I need to be able to pass a collection to another call to Activator.CreateInstance where the type being created could be a List<T>:

var values = Enumerable.Range( 1, 50 ).Select(
    I => CreateFoo( typeof( Foo ) ) ).ToArray( );
//This will explode.
var foobar = Activator.CreateInstance(
    typeof( List<Foo> ), values );

When the above is called, it explodes with the following exception:

enter image description here

I get why it is doing that - there is no constructor for a list expecting an enumerable of objects when the list is defined with a type argument.

The problem is that I cannot cast the objects because I don't know the type at runtime. Activator.CreateInstance only ever seems to return an object, which is fine for the List<Foo> because I'll be setting them using Dependency Objects and Properties, so boxed objects are perfectly fine for them, but breaks everything when trying to create a list ( and, likely, anything else with a constructor expecting a type argument ).

What is the proper method for what I am trying to get done here?

In compliance with the Minimal, Complete and Verifiable Example requirements:

using System;
using System.Collections.Generic;
using System.Linq;

namespace MCVEConsole {
    class Program {
        static int Main( string[ ] args ) {
            var values = Enumerable.Range( 1, 50 ).Select(
                I => CreateFoo( typeof( Foo ) ) ).ToArray( );

            //This will compile, but explode when run.
            var foobar = Activator.CreateInstance(
                typeof( List<Foo> ), values );
            return 1;
        }

        static dynamic CreateFoo( Type t ) =>
            Activator.CreateInstance( t );
    }

    class Foo {
        public Foo( ) { }
    }
}





Aucun commentaire:

Enregistrer un commentaire