【发布时间】:2013-01-09 14:10:49
【问题描述】:
我是一个 .NET 人,所以让我首先声明我对一些 Java 概念的理解 - 如果我错了,请纠正我。
Java 泛型支持有界通配符的概念:
class GenericClass< ? extends IInterface> { ... }
...类似于 .NET 的where 限制:
class GenericClass<T> where T: IInterface { ... }
Java 的 Class 类描述了一种类型,大致等效于 .NET Type 类
到目前为止,一切都很好。但是我找不到与 Java 通用类型 Class<T> 足够接近的等价物,其中 T 是有界通配符。这基本上对Class 所代表的类型施加了限制。
让我举一个Java的例子。
String custSortclassName = GetClassName(); //only known at runtime,
// e.g. it can come from a config file
Class<? extends IExternalSort> customClass
= Class.forName("MyExternalSort")
.asSubclass(IExternalSort.class); //this checks for correctness
IExternalSort impl = customClass.newInstance(); //look ma', no casting!
我能在 .NET 中得到的最接近的是这样的:
String custSortclassName = GetClassName(); //only known at runtime,
// e.g. it can come from a config file
Assembly assy = GetAssembly(); //unimportant
Type customClass = assy.GetType(custSortclassName);
if(!customClass.IsSubclassOf(typeof(IExternalSort))){
throw new InvalidOperationException(...);
}
IExternalSort impl = (IExternalSort)Activator.CreateInstance(customClass);
Java 版本对我来说看起来更干净。 有没有办法改进 .NET 对应项?
【问题讨论】:
-
这可能有点太简单了,但是不能简单地将
new()约束添加到 where 限制中吗?类似MyExternalSort<T> : IExternalSort where T : IExternalSort, new()然后使用var impl = new T();?我个人会使用工厂模式来创建在这种情况下实现相同接口的类型的实例。 -
我对 Java 泛型了解不多,但我知道它们的实现方式不同(不支持 JVM),并且支持许多 .NET 泛型不支持的东西。所以不要指望为所有事情找到一个直接的“等价物”
-
@Aschratt 我不明白这与我的问题有什么关系。如果在编译时知道所有类型信息,则此技巧可能很有用,但类型 MyExternalSort 直到运行时才知道 - 它很可能由我的排序库的客户端实现,并且仅由名称指定。
-
@jalf 我知道类型擦除,所以我当然不期望 1:1 映射。我只是希望对我目前不太漂亮的实现有所改进。
-
@Cristi Diaconescu:编译时不需要知道专门的类型。它只需要在编译时适应您的约束(从 IExternalSort 继承,无参数构造函数),因此当您不知道它的确切类型时,您还可以提供一些参数作为 IExternalSort 实例。
标签: java .net generics casting