我有一个问题。在框架中,这主要是在泛型来之前编写的,你经常会看到一个有很多重载的函数来做不同类型的事情。
A)
Parse(int data)
Parse(long data)
Parse(string data)
..etc
这似乎没问题,因为它有助于为每种方法保持较小的代码等等。另一方面,现在使用泛型,您可以执行以下操作:
b)中
Parse<T>(T data)
然后使用typeof()创建某种ifs / switch语句,以尝试推断出类型是什么以及如何处理它们。
什么是最佳做法?或者什么是帮助我在a)和b)之间做出选择的想法?
答案 0 :(得分:20)
恕我直言,如果你需要if / switch语句,你应该更好地重载。如果实现不依赖于具体类型仍然可以重用它,那么应该使用泛型。
作为一般规则:
答案 1 :(得分:7)
代码嗅觉。
如果你有“某种if / switch ”,那就是尖叫多态的代码味道。它表明泛型不是不是解决该问题的方法。当代码不依赖于您传入的具体类型时,应使用泛型。
观看此Google Tech会谈视频:“The Clean Code Talks -- Inheritance, Polymorphism, & Testing”。它具体针对您所谈论的内容。
答案 2 :(得分:4)
您描述使用泛型导致一堆ifs / switch语句的模式是一种反模式。
对此的一个解决方案是实现一种策略模式,允许您使用泛型,但同时将Parse方法的关注点与知道如何处理每个不同的情况隔离开来。
示例:
class SomeParser
{
void Parse<T>(ParseStrategy<T> parseStrategy, T data)
{
//do some prep
parseStrategy.Parse(data);
//do something with the result;
}
}
class ParseStrategy<T>
{
abstract void Parse(T data);
}
class StringParser: ParseStrategy<String>
{
override void Parse(String data)
{
//do your String parsing.
}
}
class IntParser: ParseStrategy<int>
{
override void Parse(int data)
{
//do your int parsing.
}
}
//use it like so
[Test]
public void ParseTest()
{
var someParser = new SomeParser();
someParser.Parse(new StringParser(), "WHAT WILL THIS PARSE TO");
}
然后你就可以传递你开发的任何策略。这样您就可以在多个类中正确地隔离您的问题,而不是违反SRP(单一责任原则。
答案 3 :(得分:2)
这里有一个问题 - 如果你要求/ switch语句使泛型有效,你可能会遇到更大的问题。在这种情况下,很有可能泛型参数不能(正确地)用于每种类型,只是您正在处理的一组固定类型。在这种情况下,您最好提供重载来单独处理特定类型。
这有很多好处:
如果你的论证可以用于任何类型,那就不那么清楚了。在这种情况下,我经常会考虑包含重载,以及类型的通用回退方法。当您将“预期”类型传递给方法时,这会提高性能,但您仍然可以使用其他非预期类型。
答案 4 :(得分:1)
虽然没有一个通用的规则,但当特定类型无关时,应使用泛型。这并不是说您不能约束类型,但这种特定类型实际上并不重要。在这种情况下,解析方法完全依赖于每种类型(并且不同)。仿制药似乎不是一个好的解决方案。