Dynamically create an object of <Type>

C#.NetDynamic

C# Problem Overview


I have a table in my database that I use to manage relationships across my application. it's pretty basic in it's nature - parentType,parentId, childType, childId... all as ints. I've done this setup before, but I did it with a switch/case setup when I had 6 different tables I was trying to link. Now I have 30 tables that I'm trying to do this with and I would like to be able to do this without having to write 30 case entries in my switch command.

Is there a way that I can make reference to a .Net class using a string? I know this isn't valid (because I've tried several variations of this):

Type t = Type.GetType("WebCore.Models.Page");
object page = new t();

I know how to get the Type of an object, but how do I use that on the fly to create a new object?

C# Solutions


Solution 1 - C#

This link should help:
https://docs.microsoft.com/en-us/dotnet/api/system.activator.createinstance

Activator.CreateInstance will create an instance of the specified type.

You could wrap that in a generic method like this:

public T GetInstance<T>(string type)
{
    return (T)Activator.CreateInstance(Type.GetType(type));
}

Solution 2 - C#

If the type is known by the caller, there's a better, faster way than using Activator.CreateInstance: you can instead use a generic constraint on the method that specifies it has a default parameterless constructor.

Doing it this way is type-safe and doesn't require reflection.

T CreateType<T>() where T : new()
{
   return new T();
}

Solution 3 - C#

public static T GetInstance<T>(params object[] args)
{
     return (T)Activator.CreateInstance(typeof(T), args);
}

I would use Activator.CreateInstance() instead of casting, as the Activator has a constructor for generics.

Solution 4 - C#

You want to use Activator.CreateInstance.

Here is an example of how it works:

using System;
using System.Runtime.Remoting;

class Program
{
	static void Main()
	{
		ObjectHandle o = Activator.CreateInstance("mscorlib.dll", "System.Int32");

		Int32 i = (Int32)o.Unwrap();
	}
}

Solution 5 - C#

Assuming you have the following type:

public class Counter<T>
{
  public T Value { get; set; }
}

and have the assembly qualified name of the type, you can construct it in the following manner:

string typeName = typeof(Counter<>).AssemblyQualifiedName;
Type t = Type.GetType(typeName);

Counter<int> counter = 
  (Counter<int>)Activator.CreateInstance(
    t.MakeGenericType(typeof(int)));

counter.Value++;
Console.WriteLine(counter.Value);

Solution 6 - C#

Here is a function I wrote that clones a record of type T, using reflection. This is a very simple implementation, I did not handle complex types etc.

 public static T Clone<T>(T original)
    {
        T newObject = (T)Activator.CreateInstance(original.GetType());

        foreach (var prop in original.GetType().GetProperties())
        {
            prop.SetValue(newObject, prop.GetValue(original));
        }

        return newObject;
    }

I hope this can help someone.

Assaf

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionthaBadDawgView Question on Stackoverflow
Solution 1 - C#Jason MiesionczekView Answer on Stackoverflow
Solution 2 - C#Judah Gabriel HimangoView Answer on Stackoverflow
Solution 3 - C#AmuuuInjuredView Answer on Stackoverflow
Solution 4 - C#Andrew HareView Answer on Stackoverflow
Solution 5 - C#sduplooyView Answer on Stackoverflow
Solution 6 - C#Assaf S.View Answer on Stackoverflow