3

我有一个 API,其中包含一些接受类型参数的方法。我现在将它们转换为泛型方法,作为改进 API(更类型安全)的一部分,同时保留非泛型版本以实现向后兼容性。

当前 - 将被淘汰:

public object MyMethod(object value, Type expectedType)

新的:

public T MyMethod<T>(object value)

然而,Mymethod 调用了一个私有的辅助方法,它也接受一个类型参数:

private object HelperMethod(object value, Type expectedType)

问题:我是否也应该使这个私有辅助方法通用?

我在下面有自己的答案,但我想知道我是否遗漏了什么。我非常感谢您的见解。

我的回答是否定的,我不应该使这个私有方法通用。

原因 1:这个辅助方法是私有的,所以即使我把它变成通用的,它也不会改进 API。

原因2:如果我让它泛型,那么非泛型的公共方法将不得不使用反射将类型参数传递给这个泛型方法,这意味着更多的开销。

4

2 回答 2

4

使您的私有辅助方法泛型确实可以通过在您的实现中始终携带泛型类型特异性来改进 API。如果您将类型限制为处理无类型 System.Objects 的核心,那么您的实现并没有完全实现泛型的类型安全优势。

例如,为什么 MyMethod 的参数仍然是 System.Object?如果该参数源自源,那么它也很有可能是类型参数。如果参数源自数据,则最好使用 System.Object。泛型在与源代码一起使用时最有用,因为源代码表达式在大多数上下文中隐式提供了类型。

泛型的隐藏成本取决于将与 API 一起使用的类型组合。如果大多数类型都是值类型(内置和结构),那么将 API 切换到泛型可能会增加内存消耗,因为泛型代码必须针对每种值类型进行不同的 jit。如果与您的通用 API 一起使用的大多数类型是引用类型(类和接口),则代码/内存爆炸不是问题,因为所有引用类型共享相同的 JIT 代码。

让旧 API 调用新的通用 API 的成本是否 a) 可测量和 b) 可接受完全取决于您在私有帮助器方法中所做的事情 - 特别是私有帮助器方法对 Type 参数所做的事情。

如果辅助方法实现相当轻量,并且您确定(通过性能测量)调整旧 API 以调用新的通用辅助方法的成本是不可接受的,我会考虑复制辅助方法实现,并排,一个在旧的样式和一个新的通用样式。这消除了 API 样式之间的交叉转换成本,并消除了将新错误引入旧 API 的风险,但代价是略微增加了内部代码维护工作。

于 2012-07-06T21:37:56.620 回答
1

我认为这取决于您计划支持非泛型方法的时间量、调用频率、对反射的影响等等等等。

我认为您会尽可能多地想要通用功能以利用您想要的类型安全性。然后在必要时改造非通用版本以使用通用版本,并最终尽快弃用它。

于 2012-07-06T21:06:24.010 回答