为什么在.NET框架的某些类中选择System.Type参数而不是泛型?

5

我注意到在.NET框架中有几个内置的类/方法需要一个System.Type类型的参数,但(在我看来)使用泛型会更加简洁明了。

例如,要创建一个DataContractSerializer实例,我需要编写如下代码:

var s = new DataContractSerializer(typeof(MyCustomClass));

替代

var s = new DataContractSerializer<MyCustomClass>();

我不想就哪种方式是“最好”的进行辩论,我更想知道为什么要以某种方式进行。 :)
一些更多的例子(来自我的头脑)包括: - System.Xml.Serialization.XmlSerializer(构造函数) - System.ServiceModel.ServiceHost(构造函数和几个方法) - System.Web.Mvc.ModelBinderAttribute

泛型直到 .Net 2.0 才被添加,因此它们不可用于早期的类。 - DOK
我在这个主题上学到的另外两个教训是:http://marcgravell.blogspot.com/2008/11/cf-woes.html和http://marcgravell.blogspot.com/2009/03/compact-framework-woes-revisted.html - Marc Gravell
Marc:有趣的阅读,谢谢分享 :) - Ozzy
2个回答

3
在使用XmlSerializer时,它是泛型出现之前的产物,这是一个很好的原因,但还有其他原因。因为我在序列化代码上花费了大量时间(通常在库代码中),我深知有时你只拥有Type的情况。简单地说,像WCF这样的库代码无法完全通用 - 这将带来很多开销和复杂性。例如,它可能只是从元素名称(或其他标记)查找Type。它事先不知道类型,因此不能在泛型(在<T>意义上)中使用。

在那些你有Type的情况下,你可以使用MakeGenericMethod等方法,但这会带来很多开销,并且实际上可能会破坏CF等(最终您开始获得缺少方法错误)。

恰巧,我最近已经将整个序列化库从以泛型作为主要API转换为以Type作为主要API。幸运的是,旧方法只需使用新方法的typeof(T)即可正常工作。


2
你提供的示例中的前两个类 - XmlSerializer 和 ServiceHost - 是在泛型出现之前设计的。也许微软可以发明一些用泛型处理的替代类,但目前还没有这样做。
通常情况下,泛型并不是必需的:如果一个方法的签名不依赖于类型,那么对调用者来说,传递 typeof(MyCustomClass) 或调用 Method<MyCustomClass> 并没有什么区别。拥有 System.Type 参数通常更有用:如果你正在编写自己的反射代码,你通常会拥有一个 System.Type。如果你只有一个 System.Type,那么调用泛型方法会更加困难。

谢谢!预日期的解释当然是显而易见的(尽管我没有提到),但另一个原因也很有道理。接受了你的答案,因为你比马克快了一分钟 :) - Ozzy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接