tags:

views:

191

answers:

7

For example, in Java, if I have a parameterized class, is it possible to do the following?

    public class MyClass<T>{
       public void aMethod {
       ..
       T object = new T();
       ..
       }
       ..

    }

In Java, I think it is not possible, because the compiler doesn't know what constructor to call. But in C#? I don't know the language and I've read that many dark things can be done, so I was just wondering..

+5  A: 

Yes, it's possible. You can use Activator.CreateInstance<T>();

From MSDN:

Activator.CreateInstance(T) Method
Creates an instance of the type designated by the specified generic type parameter, using the parameterless constructor.

Donut
+7  A: 

this is possible in C# if you are setting constraint on T type to have parameterless constructor.

public class MyClass<T> where T:new(){
   public void aMethod {
   ..
   T object = new T();
   ..
   }
   ..

}

See here.

elder_george
Putting restrictions on type is not a generic solution.
Developer Art
yes, it is not. But it provides compile-time check which is impossible when using Activator. And it fits requirements of the original poster ;)
elder_george
@Developer Art: “generic” has a fixed meaning in the context of the question in both C# and Java. Don’t redefine it arbitrarily just for the sake of controversy. This solution **is** generic, period.
Konrad Rudolph
+4  A: 

Like Donut said, C# allows you to instantiate arbitrary types at runtime using Activator.CreateInstance which works a bit like Class<?>.newInstance in Java. Since C#’s Generics are preserved after compilation, C#, unlike Java, allows you to get hold of a Type instance for a given type parameter and thus call CreateInstance or any other constructor.

For the parameterless constructor, this is considerably easier, using a generic constraint:

void <T> T createT() where T : new()
{
    return new T();
}

The key here is where T : new().

In the general case, using reflection, you can use the following:

void <T> T createT()
{
    var typeOfT = typeof(T);
    return (T) Activator.CreateInstance(typeOfT, new object[] { arg1, arg2 … });
}
Konrad Rudolph
Why is this getting downvoted? Comment?
Konrad Rudolph
Not a solution. You can't know in advance what arguments an arbitrary type is going to require.
Developer Art
@Developer Art: sorry, your common sense failed you again. Nobody is talking about completely arbitrary types, anywhere. You always need to make certain assumptions, nobody’s denying this. Code like the above works, and is actually used quite a lot. It certainly **is** “a solution” to a lot of problems. Why else would Microsoft provide the method, if it wouldn’t work?
Konrad Rudolph
@Konrad Rudolph: The question author has not specified that he's only interested in types with parameterless constructors.
Developer Art
@Developer Art: What about the "`new T()`" in the question?
Michael Myers
+3  A: 

In c# you can use the where keyword

private class MyClass<T> where T : new()
{
  private void AMethod()
  {
   T myVariable = new T();
  }
}
statenjason
A: 

To summarize, in java there is no way to instantiate a generic type T. In C#, there are several ways.

Am I understanding this correctly?

Avi
No, it's also possible in Java, though not using `new T();`. See my answer.
Jesper
+2  A: 

You can do this in Java via reflection:

public class Example {
    public static void main(String[] args) throws Exception {
        String s = create(String.class);
    }

    // Method that creates a new T
    public static <T> T create(Class<T> c) throws InstantiationException, IllegalAccessException {
        return c.newInstance();
    }
}
Jesper
+1  A: 

One of the workarounds in Java that's less ugly: Javassist.

Dean J