Problem
With the following code, you can see what I’m attempting (but failing) to achieve:
protected T GetObject()
{
return new T();
}
Any assistance would be really helpful.
EDIT:
The following was the situation: I was tinkering with a custom controller class that all controllers would inherit from, complete with standard methods. So, in this case, I needed to create a new instance of the controller type object. So, at the time of writing, it looked like this:
public class GenericController<T> : Controller
{
...
protected T GetObject()
{
return (T)Activator.CreateInstance(ObjectType);
}
public ActionResult Create()
{
var obj = GetObject()
return View(obj);
}
As a result, I thought that the best place to reflect was here. Given the question’s opening statement, I believe that the most suitable solution to mark as right was the one that used the new() constraint. That has been resolved.
Asked by Hanshan
Solution #1
Take a peek at the new Constraint feature.
public class MyClass<T> where T : new()
{
protected T GetObject()
{
return new T();
}
}
T could be a class without a default constructor, in which case new T() is an invalid statement. The new() restriction requires T to have a default constructor, thus new T() is valid.
A generic method can be subjected to the same constraint:
public static T GetObject<T>() where T : new()
{
return new T();
}
If you need to pass parameters, do so as follows:
protected T GetObject(params object[] args)
{
return (T)Activator.CreateInstance(typeof(T), args);
}
Answered by Alex Aza
Solution #2
Why hasn’t Activator.CreateInstance been suggested?
http://msdn.microsoft.com/en-us/library/wccyzw83.aspx
T obj = (T)Activator.CreateInstance(typeof(T));
Answered by Steve
Solution #3
Another option is to reflect:
protected T GetObject<T>(Type[] signature, object[] args)
{
return (T)typeof(T).GetConstructor(signature).Invoke(args);
}
Answered by Sean Thoman
Solution #4
The new constraint is good, but if T must also be a value type, use the following:
protected T GetObject() {
if (typeof(T).IsValueType || typeof(T) == typeof(string)) {
return default(T);
} else {
return (T)Activator.CreateInstance(typeof(T));
}
}
Answered by Lukas Cenovsky
Solution #5
For the sake of completeness, requiring a factory function argument is frequently the ideal solution:
T GetObject<T>(Func<T> factory)
{ return factory(); }
and rename it:
string s = GetObject(() => "result");
If necessary, you can utilize this to demand or use accessible parameters.
Answered by Joel Coehoorn
Post is based on https://stackoverflow.com/questions/6529611/c-sharp-create-new-t