Reputation: 4849
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
Upvotes: 1
Views: 991
Reputation: 383
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.
Upvotes: 2
Reputation: 29632
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.
Upvotes: 0
Reputation: 2988
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
);
Upvotes: 3