How to create a new object instance from a Type

2018-12-31 09:26发布

One may not always know the Type of an object at compile-time, but may need to create an instance of the Type. How do you get a new object instance from a Type?

12条回答
查无此人
2楼-- · 2018-12-31 09:31

If you want to use the default constructor then the solution using System.Activator presented earlier is probably the most convenient. However, if the type lacks a default constructor or you have to use a non-default one, then an option is to use reflection or System.ComponentModel.TypeDescriptor. In case of reflection, it is enough to know just the type name (with its namespace).

Example using reflection:

ObjectType instance = 
    (ObjectType)System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(
        typeName: objectType.FulName, // string including namespace of the type
        ignoreCase: false,
        bindingAttr: BindingFlags.Default,
        binder: null,  // use default binder
        args: new object[] { args, to, constructor },
        culture: null, // use CultureInfo from current thread
        activationAttributes: null
    );

Example using TypeDescriptor:

ObjectType instance = 
    (ObjectType)System.ComponentModel.TypeDescriptor.CreateInstance(
        provider: null, // use standard type description provider, which uses reflection
        objectType: objectType,
        argTypes: new Type[] { types, of, args },
        args: new object[] { args, to, constructor }
    );
查看更多
春风洒进眼中
3楼-- · 2018-12-31 09:32

The Activator class within the root System namespace is pretty powerful.

There are a lot of overloads for passing parameters to the constructor and such. Check out the documentation at:

http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx

or (new path)

https://docs.microsoft.com/en-us/dotnet/api/system.activator.createinstance

Here are some simple examples:

ObjectType instance = (ObjectType)Activator.CreateInstance(objectType);

ObjectType instance = (ObjectType)Activator.CreateInstance("MyAssembly","MyNamespace.ObjectType");
查看更多
栀子花@的思念
4楼-- · 2018-12-31 09:33

Without use of Reflection:

private T Create<T>() where T : class, new()
{
    return new T();
}
查看更多
宁负流年不负卿
5楼-- · 2018-12-31 09:33

Given this problem the Activator will work when there is a parameterless ctor. If this is a constraint consider using

System.Runtime.Serialization.FormatterServices.GetSafeUninitializedObject()
查看更多
墨雨无痕
6楼-- · 2018-12-31 09:36
ObjectType instance = (ObjectType)Activator.CreateInstance(objectType);

The Activator class has a generic variant that makes this a bit easier:

ObjectType instance = Activator.CreateInstance<ObjectType>();
查看更多
无与为乐者.
7楼-- · 2018-12-31 09:39

One implementation of this problem is to attempt to call the parameter-less constructor of the Type:

public static object GetNewObject(Type t)
{
    try
    {
        return t.GetConstructor(new Type[] { }).Invoke(new object[] { });
    }
    catch
    {
        return null;
    }
}

Here is the same approach, contained in a generic method:

public static T GetNewObject<T>()
{
    try
    {
        return (T)typeof(T).GetConstructor(new Type[] { }).Invoke(new object[] { });
    }
    catch
    {
        return default(T);
    }
}
查看更多
登录 后发表回答