我有一个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:如果我将它设为泛型,那么非泛型公共方法将不得不使用反射将类型参数传递给此泛型方法,这意味着更多的开销。
答案 0 :(得分:4)
使您的私有帮助方法通用确实通过在实现中一直带有泛型类型特性来改进API。如果你将类型限制为一个核心无类型System.Objects的核心,你的实现并没有完全实现泛型的类型安全优势。
例如,为什么MyMethod的参数仍然是System.Object?如果该参数源自source,那么它也应该是一个类型参数。如果参数源自数据,那么使用System.Object可能会更好。泛型在与源代码一起使用时最有用,因为源代码表达式在大多数上下文中隐式提供类型。
泛型的隐藏成本取决于将与API一起使用的类型组合。如果大多数类型都是值类型(内置函数和结构体),那么将API切换到泛型可能会增加内存消耗,因为对于每种值类型,通用代码必须以不同的方式进行jit。如果与通用API一起使用的大多数类型都是引用类型(类和接口),则代码/内存爆炸不是问题,因为所有引用类型共享相同的JIT代码。
旧API调用新通用API的成本是a)可测量的和b)可接受的完全取决于你在私有帮助器方法中所做的事情 - 特别是私有帮助器方法对Type的作用参数。
如果辅助方法实现相当轻量级,并且您(通过性能测量)确定调整旧API以调用新通用帮助程序的成本是不可接受的,我会考虑重复辅助方法实现,并排,一个在旧的风格和新的通用风格。这消除了API样式之间的交叉转换成本,并消除了将旧错误引入旧API的风险,但代价是内部代码维护工作略有增加。
答案 1 :(得分:1)
我认为这取决于您计划支持非通用方法的时间,调用频率,对反射的影响等等。
我认为您可以尽可能多地使用通用功能来利用您想要的类型安全性。然后根据需要改编非通用版本以使用通用版本,并最终尽快弃用它。