53

what i want to do is to automatically create some object.

In Java, class can be pass as parameter, for example

Class A{

}


Object createObjectBy(class clazz){
       // .. do construction work here
}

when using it, just ---> createObjectBy(A.class)

it is benefit for a lot of things.

so, how can i do similar thing in C#????

John Saunders
  • 160,644
  • 26
  • 247
  • 397
jojo
  • 13,583
  • 35
  • 90
  • 123

4 Answers4

63
Object createObjectBy(Type clazz){
   // .. do construction work here
    Object theObject = Activator.CreateInstance(clazz);
    return theObject;
}

Usage:

createObjectBy(typeof(A));

Or you could simply use Activator.CreateInstance directly :-)

Aviad P.
  • 32,036
  • 14
  • 103
  • 124
  • 1
    Just reminding that using this approach, your calling code should something like: Class B = (Class) CreateObjectBy(tyepof(A)); – Wagner Silveira Feb 03 '10 at 19:57
  • 3
    And this would fail if the type has no parameterless constructor – Pierre-Alain Vigeant Feb 03 '10 at 19:59
  • Hey, Aviad P, what if the class A have an argument? How could I pass it to the object theObject? – Benedito Aug 08 '18 at 20:48
  • @Benedito there's an overload of CreateInstance that accepts parameters to the constructor: https://msdn.microsoft.com/en-us/library/wcxyzt4d(v=vs.110).aspx – Aviad P. Aug 09 '18 at 06:30
  • Yeah, I saw that. But after it, I have found another problem. The class A has methods. I would like to use one of them inside the method that creates the instance. But Visual Studio indicates an compilation error, telling that "theObject" does not have such method. Do you know how to solve it? Or a place that I could look for it? – Benedito Aug 09 '18 at 16:28
  • You need to use reflection for that, and call the method by it's name which is in a string during runtime. Check this SO answer https://stackoverflow.com/a/3110313/235648 - However there is a better way to achieve that without using `Activator` or reflection at runtime, but rather during compile time, using interfaces. – Aviad P. Aug 10 '18 at 10:04
43

The ideal way would be to use generics

Type is known at design time

public static T CreateInstance<T>() where T: new()
{
    // Do some business logic
    Logger.LogObjectCreation(typeof(T));

    // Actualy instanciate the object
    return new T();
}

A call example would look like

var employee = CreateInstance<Employee>();

Type is unknown at runtime

If the type of object is unknown at runtime, for example through a plugin system, you need to use the Type class:

public static object CreateInstance(Type type)
{
    // Do some business logic
    Logger.LogObjectCreation(type);

    // Actualy instanciate the object
    return Activator.CreateInstance(type);
}

A call example would look like

var instance = CreateInstance(someType);

Performance

Of course, nothing beats instanciating an object than by using the keyword new. Except maybe not instanciating, but instead reusing an object, like through caching.

If you have to settle for the second method where the type is unknown, there are some alternatives to Activator.CreateInstance. Although the article recommend using lambda expression, your biggest consideration is:

  • Does your unknown object need to be instantiated often in a short period of time, or do you only create it once

If you only need to create your object once, just stick with the Activator.CreateInstance method. If you need to create it multiple time in a short time, try the lambda approach. That last approach is similar to a compiled regular expression vs. an on-the-fly regular expression.

Pierre-Alain Vigeant
  • 22,635
  • 8
  • 65
  • 101
  • For those who do not understand where T: new() : http://www.codeproject.com/Articles/16831/Constraints-in-Generics – RAY Jan 29 '16 at 07:11
7

Use the class Type. You can return an instance of it by call

obj.GetType();

or without an object instance

typeof(className);

I hope it helps.

CARLOS LOTH
  • 4,675
  • 3
  • 38
  • 44
6

C# doesn't support this. But what are you trying to do?

You probably could use:

createObjectBy(Type type);

or

createObjectBy<T>();
hackerhasid
  • 11,699
  • 10
  • 42
  • 60
  • 1
    I typically use both of these methods where the second one just forwards to the first. The first allows for easy calls from reflection and for lazy passing and the second allows for easy (strong-typed) calls directly from code. – Travis Gockel Feb 03 '10 at 19:57
  • often some one downvotes for unknown reason.. they dont even have the guts to comment the reason.. plus one man.. – Thameem Oct 25 '19 at 12:36