Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 525 Vote(s) - 3.48 Average
  • 1
  • 2
  • 3
  • 4
  • 5
C# Create New T()

#1
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.
Reply

#2
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.
Reply

#3
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]

Reply

#4
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]

Reply

#5
Another way is to use reflection:

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

#6
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]

Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through