想象一下,我们有以下任务:
我们必须创建一个返回输入对象类型的方法。
例如:
输入
GetTypeObject(23)
输出:
输入对象的类型是System.Int32
我认为这项任务是可以理解的吗?
现在,我可以想出两种方法来解决这个问题。
第一种方式:创建方法,其中包含if ... else语句
第二种方式:创建具有类型
的数组的方法实现
第一种方式:
private static string GetTypeOfObjectV1(object obj)
{
if (obj.GetType() == typeof (int))
return String.Format("The type of input object is {0}", obj.GetType());
if (obj.GetType() == typeof (string))
return String.Format("The type of input object is {0}", obj.GetType());
if (obj.GetType() == typeof (DateTime))
return String.Format("The type of input object is {0}", obj.GetType());
if (obj.GetType() == typeof (bool))
return String.Format("The type of input object is {0}", obj.GetType());
return null;
}
第二种方式:
private static string GetTypeOfObjectV2(object obj)
{
var listType = new List<Type> { typeof(int), typeof(string), typeof(DateTime), typeof(bool) };
return (from type in listType where obj.GetType() == type select String.Format("The type of input object is {0}", type)).FirstOrDefault();
}
运行方法:
static void Main(string[] args)
{
Stopwatch stopwatch = Stopwatch.StartNew();
Console.WriteLine(GetTypeOfObjectV1("434343"));
stopwatch.Stop();
Console.WriteLine(String.Format("GetTypeOfObjectV1 - ElapsedMilliseconds = {0}",stopwatch.ElapsedMilliseconds));
Console.WriteLine(String.Format("GetTypeOfObjectV1 - ElapsedTicks = {0}", stopwatch.ElapsedTicks));
Stopwatch stopwatch1 = Stopwatch.StartNew();
Console.WriteLine(GetTypeOfObjectV2("434343"));
stopwatch1.Stop();
Console.WriteLine(String.Format("GetTypeOfObjectV2 - ElapsedMilliseconds = {0}", stopwatch1.ElapsedMilliseconds));
Console.WriteLine(String.Format("GetTypeOfObjectV2 - ElapsedTicks = {0}", stopwatch1.ElapsedTicks));
Console.ReadKey();
}
结果:
现在,我的问题是:
哪种方式更好,为什么?
我认为第二种方式更好,因为在这种方法中我们有一些优化。例如,我想添加新类型的对象。我必须在数组中添加一个新类型。在第一种方法中,我需要用新类型创建一个新的条件。
但是,如果我没弄错的话,第一种方法比第二种方法工作得更快,并且需要的内存更少。
你怎么看?
答案 0 :(得分:6)
这是怎么回事?
private static string GetTypeOfObjectV3(object obj)
{
return string.Format("The type of input object is {0}", obj.GetType());
}
在这种情况下,没有条件会更好,因为它们不是必需的。无论输入类型如何,该语句都是相同的。
答案 1 :(得分:1)
第二种方法确实更好。如果这些类型需要从其他地方加载并且您使用第一种方法会发生什么? Nohing。没有任何东西可以工作,因为你无法将这些值添加到你的硬编码IF。那时你的第一个方法将变成第二个。
答案 2 :(得分:1)
在该特定任务中,您可能应该使用有关.net中可用类型的元信息,例如方法GetType(),在任何实例上都可用,它将为您提供有关实例类型的大量信息。
如果你想为不同的匹配类型使用不同的逻辑,你可能需要看看访问者模式,这使得继承树的工作变得更加容易。
http://en.wikipedia.org/wiki/Visitor_pattern
答案 3 :(得分:1)
虽然我没有C#经验,但似乎你可以使用函数重载的常见面向对象方法来解决这个问题。在您的类中,您可以定义getObjectType方法以接受不同类型的对象。只要它们返回相同类型的对象,它就会编译。
例如,返回字符串:
public class ObjectEvaluator
{
private static string getObjectType (Int obj) {
return String.Format("The type of input object is {0}", obj.GetType());
}
private static string getObjectType (string obj) {
return String.Format("The type of input object is {0}", obj.GetType());
}
}
或者您可能想要返回一个Type对象。在main方法中,您将创建该类的实例并调用getObjectType方法。如:
static void main ()
{
ObjectEvaluator eval = new ObjectEvaluator();
Console.WriteLine(eval.getObjectType(3));
Console.WriteLine(eval.getObjectType("something"));
}
等等。这样做的好处是多方面的。维护代码更容易:可以以模块化方式添加或删除新类型的对象,不再拖延if语句等。此方法将使您能够使用if ... else或switch语句以更健壮的方式基于对象的类型执行不同的操作。此外,性能可能可以改进,因为不需要单步执行if语句。
我希望这种方式也可以回答你的问题,即使这不是你自己提出的解决方案之一。
答案 4 :(得分:1)
关于你的问题,什么是最好的一般模式;这种代码没有best
模式。每种情况都有最佳解决方案。您需要比较可能的解决方案,并根据手头的问题权衡利弊。
可能的解决方案:
GetType()
解决方案是最简单和优雅的模式,但只有当您正在评估的对象具有满足您需要的方法时才有可能。
if/else
解决方案对于简单情况很有用,其中可能的答案列表是有限的(经验法则:3或更少)。此解决方案是硬编码的,需要针对每种情况进行修改。
switch
语句使代码可以管理更长的列表操作选项。这是编写if / else逻辑的更好方法。该解决方案也是硬编码的。性能可能比if / else好。
一个table/list lookup
解决方案很好,你只需要编写一次列表查找代码。如果列表变长,该代码不会更改。您使用基于列表的方法遇到的问题是您需要找到填充该列表的方法,并且必须维护该方法。您可以从文件中读取列表,或使用反射扫描对象等...此方法是预取答案的方法。
使用business rules
的解决方案包含一组规则,一种针对给定数据执行这些规则的方法,以及一种将结果评估为最终答案的方法。
Fuzzy logic
结合多项评估,并权衡它们,从而得出best
答案。有点像你需要做的选择这些选项: - )
希望这有帮助。