是否可以在Java或C#中实例化泛型类型的对象?

lur*_*rks 0 c# java generics

例如,在Java中,如果我有参数化类,是否可以执行以下操作?

public class MyClass<T>{
  public void aMethod {
    ..
    T object = new T();
    ..
  }
  ..
}
Run Code Online (Sandbox Code Playgroud)

在Java中,我认为这是不可能的,因为编译器不知道要调用什么构造函数.但在C#?我不懂语言而且我读过很多黑暗的东西都可以做,所以我只是想知道..

eld*_*rge 9

如果要在T类型上设置约束以使其具有无参数构造函数,则可以在C#中实现.

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

}
Run Code Online (Sandbox Code Playgroud)

看到这里.

  • @Developer Art:"generic"在C#和Java中的问题上下文中都有固定的含义.不要仅仅为了争议而任意重新定义它.此解决方案**是**通用的,期间. (3认同)
  • 是的,事实并非如此.但它提供了编译时检查,这在使用Activator时是不可能的.它符合原始海报的要求;) (2认同)

Kon*_*lph 6

就像Donut说的那样,C#允许你在运行时实例化任意类型,Activator.CreateInstance就像Class<?>.newInstance在Java中一样.由于C#的Generics在编译后保留,因此与Java不同,C#允许您获取Type给定类型参数的实例,从而调用CreateInstance或任何其他构造函数.

对于无参数构造函数,使用通用约束会相当容易:

void <T> T createT() where T : new()
{
    return new T();
}
Run Code Online (Sandbox Code Playgroud)

这里的关键是where T : new().

在一般情况下,使用反射,您可以使用以下内容:

void <T> T createT()
{
    var typeOfT = typeof(T);
    return (T) Activator.CreateInstance(typeOfT, new object[] { arg1, arg2 … });
}
Run Code Online (Sandbox Code Playgroud)

  • @Developer Art:对不起,你的常识再次失败了.没有人在任何地方谈论完全任意的类型.你总是需要做出某些假设,没有人否认这一点.像上面的代码工作,实际上使用了很多.它肯定**是解决许多问题的"解决方案".为什么Microsoft会提供该方法,如果它不起作用? (3认同)
  • @Developer Art:问题中的"新T()`"怎么样? (3认同)

Don*_*nut 5

是的,这是可能的.您可以使用Activator.CreateInstance<T>();

来自MSDN:

Activator.CreateInstance(T)方法
使用无参数构造函数创建由指定的泛型类型参数指定的类型的实例.