Reputation: 1889
One thing that irritates me about Java is the awful implementation of compile-time translation of generic type arguments.
I can observe and understand that the C# implementation is far better, but I'm confused as to how it works.
Essentially, how can you say:
T t = new T()
If you don't know the type of T and therefore don't know the constructor argument requirements?
I can see
Class<T> cl = T.class
or
T[] tarr = new T[0]
but I don't see how you can really create a new instance of T if you don't know the requirements of constructing it?
Upvotes: 1
Views: 218
Reputation: 67108
Actually you ask the compiler to force T
to have a parameterless constructor so he knows you can new T()
. For example:
class Test<T>
{
T Create()
{
return new T();
}
}
It won't compile because the compiler can't be sure that T
won't be an abstract class and that it'll have a default constructor. To make it works you have to add a constrain on the real type of T:
class Test<T> where T : new()
Now the compiler will force T
to be a non abstract class with a default constructor. For example this code is not valid because the given type is abstract:
abstract class AnotherTest
{
public void Test()
{
Test<Derived> test = new Test<Derived>();
}
}
Again, if you try to use a class without default constructor the compiler will emit an error:
class AnotherTest
{
public AnotherTest(string someParameter)
{
}
public void Test()
{
Test<Derived> test = new Test<Derived>();
}
}
With an array it's a little bit different. Actually you simply ask the compiler to reserve the memory for a given number of slots, you do not allocate the memory for that objects (in case of reference types it'll simply put null
in each slot).
References on MSDN
Upvotes: 2
Reputation: 8513
new T()
is just a syntactical sugar for Activator.CreateInstance<T>()
Upvotes: 0
Reputation: 51359
You can only do new T();
if T is constrained to have a plain, parameterless public constructor, for instance:
public class Foo<T> where T : new() {
private myT = new T();
}
Additionally, there is no way to specify that any other sort of constructor exist. This is not possible:
// Doesn't work
public class Foo<T> where T : new(String, Int) {
private myT = new T("Foo", 5);
}
To your other points, this is how you get the type of T at runtime:
var tType = typeof(T);
and creating an array of T
doesn't actually create any instances (unless T
is a value type, in which case it creates the default value of that type):
// Space for 32 T's, but nothing in the array.
// If T is a value type, like an int for instance,
// each one would have the default value (0 for int, for example)
var arrayOfT = new T[32];
Upvotes: 4
Reputation: 54897
You cannot say new T()
unless you constrain your generic type to have a parameterless constructor using the where T : new()
constraint — see Constraints on Type Parameters.
And there are no “constructor argument requirements”, since the only supported constructor is the parameterless one. You cannot use, say, new T(false)
— constraints of the form where T : new(bool)
are not allowed.
Upvotes: 2