How to create a new object instance from a Type

后端 未结 12 1730
孤城傲影
孤城傲影 2020-11-22 03: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 objec

相关标签:
12条回答
  • 2020-11-22 03:51

    Its pretty simple. Assume that your classname is Car and the namespace is Vehicles, then pass the parameter as Vehicles.Car which returns object of type Car. Like this you can create any instance of any class dynamically.

    public object GetInstance(string strNamesapace)
    {         
         Type t = Type.GetType(strNamesapace); 
         return  Activator.CreateInstance(t);         
    }
    

    If your Fully Qualified Name(ie, Vehicles.Car in this case) is in another assembly, the Type.GetType will be null. In such cases, you have loop through all assemblies and find the Type. For that you can use the below code

    public object GetInstance(string strFullyQualifiedName)
    {
         Type type = Type.GetType(strFullyQualifiedName);
         if (type != null)
             return Activator.CreateInstance(type);
         foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
         {
             type = asm.GetType(strFullyQualifiedName);
             if (type != null)
                 return Activator.CreateInstance(type);
         }
         return null;
     }
    

    And you can get the instance by calling the above method.

    object objClassInstance = GetInstance("Vehicles.Car");
    
    0 讨论(0)
  • 2020-11-22 03:52

    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 }
        );
    
    0 讨论(0)
  • 2020-11-22 03:55

    If this is for something that will be called a lot in an application instance, it's a lot faster to compile and cache dynamic code instead of using the activator or ConstructorInfo.Invoke(). Two easy options for dynamic compilation are compiled Linq Expressions or some simple IL opcodes and DynamicMethod. Either way, the difference is huge when you start getting into tight loops or multiple calls.

    0 讨论(0)
  • 2020-11-22 03:56

    I can across this question because I was looking to implement a simple CloneObject method for arbitrary class (with a default constructor)

    With generic method you can require that the type implements New().

    Public Function CloneObject(Of T As New)(ByVal src As T) As T
        Dim result As T = Nothing
        Dim cloneable = TryCast(src, ICloneable)
        If cloneable IsNot Nothing Then
            result = cloneable.Clone()
        Else
            result = New T
            CopySimpleProperties(src, result, Nothing, "clone")
        End If
        Return result
    End Function
    

    With non-generic assume the type has a default constructor and catch an exception if it doesn't.

    Public Function CloneObject(ByVal src As Object) As Object
        Dim result As Object = Nothing
        Dim cloneable As ICloneable
        Try
            cloneable = TryCast(src, ICloneable)
            If cloneable IsNot Nothing Then
                result = cloneable.Clone()
            Else
                result = Activator.CreateInstance(src.GetType())
                CopySimpleProperties(src, result, Nothing, "clone")
            End If
        Catch ex As Exception
            Trace.WriteLine("!!! CloneObject(): " & ex.Message)
        End Try
        Return result
    End Function
    
    0 讨论(0)
  • 2020-11-22 03:59

    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()
    
    0 讨论(0)
  • 2020-11-22 04:06
    public AbstractType New
    {
        get
        {
            return (AbstractType) Activator.CreateInstance(GetType());
        }
    }
    
    0 讨论(0)
提交回复
热议问题