You can see what I'm trying (but failing) to do with the following code:
protected T GetObject()
{
return new T();
}
Any help would be greatly appreciated.
EDIT:
The context was as follows. I was playing around with a custom controller class for all controllers to derive from, with standardised methods. So in context, I needed to create a new instance of the object of the controller type. So at time of writing, it was something like:
public class GenericController<T> : Controller
{
...
protected T GetObject()
{
return (T)Activator.CreateInstance(ObjectType);
}
public ActionResult Create()
{
var obj = GetObject()
return View(obj);
}
And so I decided reflection was easiest here. I agree that, certainly given the initial statement of the question, the most appropriate answer to mark as correct was the one using the new() constraint. I have fixed that up.
Take a look at new Constraint
public class MyClass<T> where T : new()
{
protected T GetObject()
{
return new T();
}
}
T
could be a class that does not have a default constructor: in this case new T()
would be an invalid statement. The new()
constraint says that T
must have a default constructor, which makes new T()
legal.
You can apply the same constraint to a generic method:
public static T GetObject<T>() where T : new()
{
return new T();
}
If you need to pass parameters:
protected T GetObject(params object[] args)
{
return (T)Activator.CreateInstance(typeof(T), args);
}
Why hasn't anyone suggested Activator.CreateInstance
?
http://msdn.microsoft.com/en-us/library/wccyzw83.aspx
T obj = (T)Activator.CreateInstance(typeof(T));
Another way is to use reflection:
protected T GetObject<T>(Type[] signature, object[] args)
{
return (T)typeof(T).GetConstructor(signature).Invoke(args);
}
The new constraint is fine, but if you need T being a value type too, use this:
protected T GetObject() {
if (typeof(T).IsValueType || typeof(T) == typeof(string)) {
return default(T);
} else {
return (T)Activator.CreateInstance(typeof(T));
}
}
Just for completion, the best solution here is often to require a factory function argument:
T GetObject<T>(Func<T> factory)
{ return factory(); }
and call it something like this:
string s = GetObject(() => "result");
You can use that to require or make use of available parameters, if needed.
Since this is tagged C# 4. With the open sourece framework ImpromptuIntereface it will use the dlr to call the constructor it is significantly faster than Activator when your constructor has arguments, and negligibly slower when it doesn't. However the main advantage is that it will handle constructors with C# 4.0 optional parameters correctly, something that Activator won't do.
protected T GetObject(params object[] args)
{
return (T)Impromptu.InvokeConstructor(typeof(T), args);
}
To get this i tried following code :
protected T GetObject<T>()
{
T obj = default(T);
obj =Activator.CreateInstance<T>();
return obj ;
}
Success story sharing