Question

How to Create an Object Instance from a Type in C#

csharp.netperformancereflectiontypes

Question

In C#, you may not always know an object's type at compile time, but you may still need to create an instance of that type at runtime.

How can you create a new object instance when all you have is a Type?

For example, the goal is to create an instance dynamically from something like:

Type type = /* some runtime type */;

and then produce a new object of that type.

Short Answer

By the end of this page, you will understand how to create objects dynamically in C# when you only have a Type at runtime. You will learn the most common approach using Activator.CreateInstance, how constructors affect object creation, when reflection is useful, and what mistakes to avoid when instantiating types dynamically.

Concept

In normal C# code, object creation usually happens with the new keyword:

var user = new User();

That works when the type is known at compile time. But sometimes a program discovers the type later, while it is running. This happens in scenarios like:

  • plugin systems
  • dependency injection containers
  • serializers
  • configuration-driven object creation
  • test frameworks

When all you have is a Type object, you cannot write:

new type(); // invalid

because new requires a compile-time type name, not a runtime Type value.

This is where Activator.CreateInstance becomes useful. It lets you ask the runtime to create an object from a Type.

object instance = Activator.CreateInstance(type);

This creates a new instance of the specified type, usually by calling its parameterless constructor.

Why this matters:

  • It allows flexible, extensible programs.
  • It supports runtime discovery of classes.
  • It is a core part of reflection-based programming.

However, dynamic creation comes with trade-offs:

  • less compile-time safety
  • possible runtime errors if constructors do not match
  • often slower than direct new

So it is powerful, but should be used intentionally.

Mental Model

Think of Type as a blueprint label, not the actual building.

  • new User() means: "Build me a house from the User blueprint I already know."
  • Type type = ... means: "Here is a label that tells you which blueprint to use, but you only find out at runtime."
  • Activator.CreateInstance(type) means: "Use this blueprint label and build one instance now."

So Type tells you what something is, and Activator.CreateInstance is the worker that actually builds it.

Take Quiz

Syntax and Examples

Basic syntax

object instance = Activator.CreateInstance(type);

This returns an object, because the compiler may not know the exact type.

Example with a parameterless constructor

using System;

class Person
{
    public string Name { get; set; }
}

class Program
{
    static void Main()
    {
        Type type = typeof(Person);
        object instance = Activator.CreateInstance(type);

        Person person = (Person)instance;
        person.Name = "Ava";

        Console.WriteLine(person.Name);
    }
}

What this does

  • typeof(Person) gets the runtime Type.
  • Activator.CreateInstance(type) creates a new Person.
  • The result is returned as object.
  • You cast it back to Person if needed.

Example with constructor arguments

If the type does not have a parameterless constructor, you can pass arguments:

using System;

class Person
{
    public string Name { get; }

    public Person(string name)
    {
        Name = name;
    }
}

class Program
{
    static void Main()
    {
        Type type = typeof(Person);
        object instance = Activator.CreateInstance(type, "Liam");

        Person person = (Person)instance;
        Console.WriteLine(person.Name);
    }
}

The runtime looks for a constructor that matches the provided arguments.

Generic version

If the type is known in generic code, you can use:

T item = Activator.CreateInstance<T>();

This is useful in generic methods when T is the type parameter.

using System;

class Program
{
    static T Create<T>()
    {
        return Activator.CreateInstance<T>();
    }
}

This still depends on the runtime being able to construct T.

Step by Step Execution

Consider this example:

using System;

class Message
{
    public string Text { get; set; } = "Hello";
}

class Program
{
    static void Main()
    {
        Type type = typeof(Message);
        object instance = Activator.CreateInstance(type);
        Message message = (Message)instance;

        Console.WriteLine(message.Text);
    }
}

Step by step

  1. Type type = typeof(Message);

    • The program gets metadata describing the Message class.
    • No object is created yet.
  2. object instance = Activator.CreateInstance(type);

    • The runtime checks the Message type.
    • It finds a usable parameterless constructor.
    • It creates a new Message object.
    • The result is stored as object.
  3. Message message = (Message)instance;

    • The code casts the general object reference back to Message.
    • Now you can access Message members directly.
  4. Console.WriteLine(message.Text);

    • The Text property value is printed.
    • Output:
Hello

Key idea

Type gives the runtime enough information to create the object, but the compiler still treats the result as object unless you cast it or work with a common interface or base class.

Real World Use Cases

Plugin systems

An app may load class names from assemblies and create plugin objects dynamically.

Type pluginType = loadedAssembly.GetType("MyApp.Plugins.CsvExporter");
object plugin = Activator.CreateInstance(pluginType);

Configuration-based services

A configuration file may specify which implementation to use.

  • EmailSender
  • SmsSender
  • PushNotificationSender

The application resolves the type at runtime and creates it.

Testing frameworks

Test runners often discover test classes through reflection and instantiate them automatically.

Serialization and mapping tools

Libraries may create objects before populating their properties from JSON, XML, or database records.

Command or job processors

A background worker may discover a job type from a queue message and instantiate the appropriate handler.

Take Quiz

Real Codebase Usage

In real projects, developers usually combine runtime object creation with safer design patterns.

Common patterns

Create via interface or base class

Instead of using the created object as plain object, cast to a known abstraction:

IPlugin plugin = (IPlugin)Activator.CreateInstance(type);
plugin.Run();

This makes the rest of the code cleaner and safer.

Guard clauses before creation

Real code often validates the type first:

if (type == null)
    throw new ArgumentNullException(nameof(type));

if (type.IsAbstract || type.IsInterface)
    throw new InvalidOperationException("Type cannot be instantiated.");

Constructor matching

If arguments are needed, code ensures the right constructor exists.

object service = Activator.CreateInstance(type, connectionString);

Error handling

Because dynamic creation can fail at runtime, developers often wrap it:

try
{
    return Activator.CreateInstance(type);
}
catch (Exception ex)
{
    throw new InvalidOperationException($"Could not create instance of {type.FullName}", ex);
}

Factories over direct reflection

In larger codebases, teams often hide reflection behind a factory method or service. That keeps the rest of the app simple.

public object Create(Type type)
{
    return Activator.CreateInstance(type);
}

This is easier to test and replace later.

Common Mistakes

1. Trying to use new with a Type

Broken code:

Type type = typeof(string);
// var x = new type(); // invalid

Why it fails:

  • new needs a real type name at compile time.
  • type is just a variable holding metadata.

Use this instead:

object x = Activator.CreateInstance(type);

2. Assuming every type has a parameterless constructor

Broken code:

class Person
{
    public Person(string name) { }
}

Type type = typeof(Person);
object instance = Activator.CreateInstance(type); // fails

Fix:

object instance = Activator.CreateInstance(type, "Mia");

3. Trying to instantiate interfaces or abstract classes

Broken code:

Type type = typeof(IDisposable);
object instance = Activator.CreateInstance(type); // fails

Fix:

  • Use a concrete class.
  • Check type.IsInterface and type.IsAbstract first.

4. Forgetting to cast the result

Activator.CreateInstance returns object.

object instance = Activator.CreateInstance(typeof(Person));

You must cast it if you need specific members:

Person person = (Person)instance;

5. Ignoring runtime exceptions

Dynamic creation can fail for many reasons:

  • no matching constructor
  • constructor throws an exception
  • type cannot be instantiated

Always consider error handling when the type comes from outside your code.

6. Using reflection when a simpler design would work

Sometimes a dictionary of factory functions is simpler and safer than runtime reflection.

var factories = new Dictionary<string, Func<object>>
{
    ["person"] = () => new Person(),
    ["order"] = () => new Order()
};

If the set of types is known, this may be better than Activator.CreateInstance.

Comparisons

ApproachWhen to useProsCons
new MyClass()Type known at compile timeFast, safe, simpleNot dynamic
Activator.CreateInstance(type)Type known only at runtimeFlexible, built into .NETRuntime errors possible
Activator.CreateInstance(type, args)Runtime type with constructor parametersCan call matching constructorsMore fragile if arguments do not match
Generic new() constraintGeneric code with parameterless constructorCompile-time safetyOnly works for parameterless constructors
Factory methodKnown set of typesClear, testable, maintainableLess dynamic

Activator.CreateInstance vs generic new()

where T : new()

This allows:

T item = new T();

Comparison:

FeatureActivator.CreateInstancenew() constraint
Runtime Type supportYesNo
Compile-time safetyLowerHigher
Requires parameterless constructorUsually, unless args are providedYes
Best forReflection and dynamic systemsGeneric helper methods
Take Quiz

Cheat Sheet

Quick reference

Create an instance from a Type

object instance = Activator.CreateInstance(type);

Create with constructor arguments

object instance = Activator.CreateInstance(type, arg1, arg2);

Generic version

T instance = Activator.CreateInstance<T>();

Rules to remember

  • new SomeType() works only when the type is known at compile time.
  • Activator.CreateInstance works when the type is known only at runtime.
  • The return type is usually object.
  • Cast the result to a known interface, base class, or concrete type.
  • The target type must be instantiable.

Common checks

if (type == null)
    throw new ArgumentNullException(nameof(type));

if (type.IsInterface || type.IsAbstract)
    throw new InvalidOperationException("Type cannot be instantiated.");

Common failure reasons

  • no matching constructor
  • abstract class
  • interface
  • constructor throws exception
  • wrong argument list

Good practice

  • Prefer interfaces or base classes after creation.
  • Use factories if the possible types are known.
  • Add error handling when the type comes from configuration, files, or external assemblies.

FAQ

How do I create an instance from a Type in C#?

Use Activator.CreateInstance(type). It asks the runtime to create an object for that Type.

Can I use new with a Type variable?

No. The new keyword requires a compile-time type name, not a runtime Type value.

What happens if the type has no default constructor?

You must pass matching constructor arguments, for example:

Activator.CreateInstance(type, "value")

Why does Activator.CreateInstance return object?

Because the compiler may not know the specific type in advance. You usually cast it to a known type, interface, or base class.

Can I create interfaces or abstract classes this way?

No. Interfaces and abstract classes cannot be instantiated directly.

Is Activator.CreateInstance slower than new?

Yes, generally it is slower because it uses runtime mechanisms. For most normal code, prefer new when possible.

When should I avoid dynamic instantiation?

Avoid it when the set of types is already known. In those cases, direct construction or factory methods are usually simpler and safer.

Take Quiz

Mini Project

Description

Build a small runtime object factory in C#. The program should accept a Type, create an instance if possible, and print information about the created object. This demonstrates practical use of Activator.CreateInstance, type validation, and safe casting.

Goal

Create a reusable method that instantiates valid runtime types and rejects types that cannot be created.

Requirements

  • Create at least two sample classes that can be instantiated.
  • Add one type that cannot be instantiated directly, such as an abstract class or interface.
  • Write a method that accepts a Type and returns a new object instance.
  • Validate the type before instantiating it.
  • Print success or error messages for each test type.
Take Quiz

Keep learning

Related questions

View more