0Day Forums
C# Create New T() - Printable Version

+- 0Day Forums (https://0day.red)
+-- Forum: Coding (https://0day.red/Forum-Coding)
+--- Forum: C# (https://0day.red/Forum-C)
+--- Thread: C# Create New T() (/Thread-C-Create-New-T)



C# Create New T() - lawinesy - 07-24-2023

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.


RE: C# Create New T() - mislike160 - 07-24-2023

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.


RE: C# Create New T() - periodates277239 - 07-24-2023

The [new constraint][1] 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));
}
}


[1]:

[To see links please register here]




RE: C# Create New T() - Siragvoihwku - 07-24-2023

Since this is tagged C# 4. With the open sourece framework [ImpromptuIntereface][1] 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);
}


[1]:

[To see links please register here]




RE: C# Create New T() - weaklinesses8439 - 07-24-2023

Another way is to use reflection:

protected T GetObject<T>(Type[] signature, object[] args)
{
return (T)typeof(T).GetConstructor(signature).Invoke(args);
}


RE: C# Create New T() - rickrdem - 07-24-2023

Take a look at [new Constraint][1]

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);
}



[1]:

[To see links please register here]