C# 哪种方法更好(使用if..else语句还是不使用)

C# 哪种方法更好(使用if..else语句还是不使用),c#,.net,C#,.net,假设我们有以下任务: 我们必须创建一个返回输入对象类型的方法 例如: private static string GetTypeOfObjectV1(object obj) { if (obj.GetType() == typeof (int)) return String.Format("The type of input object is {0}", obj.GetType()); if (ob

假设我们有以下任务:

我们必须创建一个返回输入对象类型的方法

例如:

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();
        }
输入:

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();
        }
GetTypeObject(23)

输出:

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();
        }
输入对象的类型为System.Int32

我认为这项任务是可以理解的

现在,我可以想出两种方法来解决这个问题

第1种方法:创建包含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();
        }
第二种方式:

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();
        }
结果:

现在,我的问题是:

什么方法更好?为什么?

我认为第二种方法更好,因为在这种方法中我们有一些优化。例如,我想添加新类型的对象。我必须在数组中添加一个新类型。在第一个方法中,我需要创建一个具有新类型的新条件

但是,如果我没有弄错的话,第一种方法比第二种方法工作得更快,并且需要更少的内存


你觉得怎么样?

第二种方法确实更好。如果这些类型需要从其他地方加载,而您正在使用第1种方法,会发生什么情况?诺兴。因为您无法将这些值添加到硬编码的IFs中,所以“无”中的任何内容都不会起作用。这时,你的第一个方法将变成第二个方法。

简单地说这是怎么回事

private static string GetTypeOfObjectV3(object obj)
{
    return string.Format("The type of input object is {0}", obj.GetType());
}

在这种情况下,最好不要有任何条件,因为它们只是不必要的。无论输入类型如何,该语句都是相同的。

在该特定任务中,您可能应该使用.net中可用类型的元信息,例如在任何实例上可用的方法GetType(),它将为您提供有关实例类型的大量信息

如果您想要为不同的匹配类型使用不同的逻辑,您可能需要查看访问者模式,这使得使用继承树更容易



虽然我对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());
        }
   }
或者,您可能希望返回类型对象。在main方法中,您将创建类的实例并调用getObjectType方法。例如:

static void main () 
{
    ObjectEvaluator eval = new ObjectEvaluator();
    Console.WriteLine(eval.getObjectType(3));
    Console.WriteLine(eval.getObjectType("something"));
}
等等。这样做的好处是多方面的。维护代码更容易:可以以模块化的方式添加或删除新类型的对象,不再需要拖拽if语句等。这种方法将使您能够基于对象的类型以更健壮的方式执行不同的操作,而使用if。。。else或switch语句。此外,性能可能会得到改进,因为不需要单步执行if语句


我希望这种方式也能回答您的问题,即使这不是您自己提出的解决方案之一。

关于您的问题,什么是最佳的一般模式;这种代码没有最佳模式。对于每一个给定的情况,都有一个可能的最佳解决方案。您需要比较可能的解决方案,并根据手头的问题权衡利弊

可能的解决办法:

  • .GetType()解决方案
  • if/else if/else逻辑
  • 开关语句
  • 表格/列表查找
  • 业务规则逻辑
  • 模糊逻辑解
  • 其他内容(自定义编码)
  • GetType()
    解决方案是最简单、最优雅的模式,但只有当您正在计算的对象具有满足您需要的方法时,才有可能实现

    if/else
    解决方案适用于可能答案列表有限的简单情况(经验法则:3或更少)。此解决方案是硬编码的,需要针对每种情况进行修改

    switch
    语句使代码可管理更长的选项列表。这是写if/else逻辑的更好方法。这个解决方案也是硬编码的。性能可以比if/else更好

    表/列表查找
    解决方案很好,因为您只需要编写一次列表查找代码。如果列表变长,则该代码不会更改。使用基于列表的方法时遇到的问题是,您需要找到一种方法来填充该列表,并且必须维护该方法。您可以从文件中读取列表,或使用反射扫描对象,等等。。。此方法是预取答案的一种方法

    使用
    业务规则的解决方案
    包含一组规则、针对给定数据执行这些规则的方法,以及评估结果以得出最终答案的方法

    模糊逻辑
    将多个评估组合在一起,并对它们进行加权,从而得出
    最佳
    答案。有点像在这些选项中选择所需的操作:-)


    希望这有帮助。

    为什么不进行反思?每个对象都有一个
    .GetType()
    方法。@Benjaminidele对不起,你能解释一下在这种情况下如何使用反射吗?@netwer在
    getTypeOfObject v1
    中,每个
    if
    语句的主体都完全相同。为什么不删除
    if
    语句,只使用
    返回string.Format(“输入对象的类型是{0}”,obj.GetType())作为函数体?这将使函数适用于每种输入类型。@netwer您的第一种方法是不带lot if条件的答案:)@netwer为什么要在if/else逻辑或表驱动解决方案之间进行选择?您还没有看
    开关
    语句吗?正如在软件开发的许多方面一样,没有一个“黄金”解决方案最适合每种情况。如果有可能的话,那就只有这样了