1

I was just going through some articles on reflection and generics, and I came across the following code:

public static T CreateControlInstance<T>(FormControl parent) 
    where T : FormControl
{            
    T control = GetControlInstance<T>(parent);
    //do something with control
} 

public static T GetControlInstance<T>(FormControl parent)
{
      return (T)Activator.CreateInstance(typeof(T), new object[] { parent });
} 

These methods were used like this:

MyButton b = CreateControlInstance<MyButton>(SomeformInstance);

Many controls were created this way. I would just like to know:

Q1. What are the advantages of this approach?

Q2. What are the advantages of this approach, given that the object instance types are known at compile time? (I'm assuming that the button and FormControl were somehow related to System.Windows.Forms.Control)

Edit:
I found something similar being done here Create instance of generic type?

Basically i want to create type(of known type) from strings which got read at runtime?
I wanted to avoid long list of if-then-else in creating objects of specific type depending on the string..but didn't have a clue.
Any one has better solution so that reflection can be avoided to create elements of known type.
End Edit

Community
  • 1
  • 1
Amitd
  • 4,769
  • 8
  • 56
  • 82

3 Answers3

3

The problem with generics is that you can't define a constraint on a complex constructor. The only constraint is the availability of an empty constructor.

public static T CreateInstance<T>() where T : new()
{
  return new T();
}

However, when you want to pass parameter, you'll have to use other methods, such as Activator.CreateInstance. You can also use lambda.

public static T CreateInstance<T>(Func<FormControl, T> builder, FormControl parent)
{
  return builder(parent);
}

But you'll have to provide a specific lambda for constructing your object, for each different object.

MyButton b = CreateInstance<MyButton>(parent => new MyButton(parent), SomeformInstance);

By using reflection, you can make code simpler and automatically use a pre-defined constructor. But by using lambda, you can use class that don't match a given convention and fill other constructor arguments with you own data.

var b2 = CreateInstance<MyOtherButton>(
  parent => new MyOtherButton("name", 42, parent), SomeformInstance
);
Nekresh
  • 2,948
  • 23
  • 28
2

If you are going to create a lot of controls this way, you'll notice that your app will be running slow. This is because Activator.CreateInstance is 10000 times slower than simple new(). Do keep that in mind.

Ravi
  • 383
  • 3
  • 6
  • even for instances created locally? i thought createinstance was a slower but not that much slower.. – Amitd Feb 08 '11 at 05:41
  • Yes. time the calls to new() vs Activator.CreateInstance() and you'll find it. FWIU, Activator.CreateInstance() goes through quite a few security checks, reflection and other stuff before it gets to create the object. This overhead is nearly 10000 times that of a simple IL call that is new(). – Ravi Jul 14 '11 at 08:22
  • 1
    All this has been true only for pre-.NET 4 versions. Since then its almost equal – nawfal Apr 23 '13 at 07:27
0

The only advantage is that you can perform extra processing.

You could e.g. expand the CreateControlInstance<T> method with some extra processing which needs to be performed for ever control.

However, when the choice is between

MyButton b = CreateControlInstance<MyButton>(SomeformInstance);

and

MyButton b = new MyButton(SomeformInstance);

There is absolutely no reason to not choose the latter. The former will perform worse and will clutter your code unnecessarily.

Pieter van Ginkel
  • 29,160
  • 8
  • 71
  • 111