Reputation: 3764
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.
Upvotes: 218
Views: 233485
Reputation: 27
I tried
if (typeof(T).IsValueType || typeof(T) == typeof(string))
return default(T);
return Activator.CreateInstance<T>();
But when running it it threw this error at return Activator.CreateInstance<T>();
System.MissingMethodException: 'No parameterless constructor defined for this object.'
The types of T that got used where int
and List<int>
Upvotes: 0
Reputation: 31652
Why hasn't anyone suggested Activator.CreateInstance
?
http://msdn.microsoft.com/en-us/library/wccyzw83.aspx
T obj = (T)Activator.CreateInstance(typeof(T));
Upvotes: 124
Reputation: 861
To get this i tried following code :
protected T GetObject<T>()
{
T obj = default(T);
obj =Activator.CreateInstance<T>();
return obj ;
}
Upvotes: 6
Reputation: 78487
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);
}
Upvotes: 526
Reputation: 7489
Another way is to use reflection:
protected T GetObject<T>(Type[] signature, object[] args)
{
return (T)typeof(T).GetConstructor(signature).Invoke(args);
}
Upvotes: 31
Reputation: 31809
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);
}
Upvotes: 7
Reputation: 5670
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));
}
}
Upvotes: 21
Reputation: 416059
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.
Upvotes: 19