4

如果变量的数据类型与某个基本类型匹配,我有一些需要执行的代码片段。目前我正在使用 if-else 循环执行此操作

前任:

  if(a is float)
  {
   // do something here
  }
  else if (a is int)
  {
  // do something here
  }
  else if (a is string)
  {
  // do something here
  }

由于我必须比较的类型太多,因此使用 If else 非常笨拙。由于 C# 不允许类型切换,有没有其他方法可以做到这一点?

4

4 回答 4

5

重构代码并使用方法重载

void SomeCode()
{
    ...
    Action(3.0f); // calls float overload
    Action("hello"); // calls string overload
    ...
}

void Action(float a)
{
    ...
}
void Action(int a)
{
    ...
}
void Action(string a)
{
    ...
}

编辑:
通过使用dynamic关键字(.NET 4),它以这种方式工作(完整的控制台应用程序):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            SomeCode();
        }

        static void SomeCode()
        {
            object o = null;
            switch (new Random().Next(0, 3))
            {
                case 0:
                    o = 3.0f;
                    break;
                case 1:
                    o = 3.0d;
                    break;
                case 2:
                    o = "hello";
                    break;
            }
            Action((dynamic)o); // notice dynamic here
        }

        static void Action(dynamic a)
        {
            Console.WriteLine("object");
        }

        static void Action(float a)
        {
            Console.WriteLine("float");
        }
        static void Action(int a)
        {
            Console.WriteLine("int");
        }
        static void Action(string a)
        {
            Console.WriteLine("string");
        }
    }
}
于 2013-08-02T12:28:28.827 回答
2

您可以创建一个Dictionary<Type, Action<object>>并存储类型(从GetType方法返回值a以及执行您希望为给定类型运行的任何代码的委托。

例如,看看这个:

private readonly Dictionary<Type, Action<object>> typeActions = new Dictionary<Type, Action<object>>()
{
    { typeof(int), (a) => { Console.WriteLine(a.ToString() + " is an integer!"); } },
    { typeof(float), (a) => { Console.WriteLine(a.ToString() + " is a single-precision floating-point number!"); } }
};

然后可以在您的代码中的其他地方使用此字典:

Action<object> action;
if (typeActions.TryGetValue(a.GetType(), out action)) {
    action(a);
}

请注意,您仍然必须a在您的操作中强制转换为适当的类型。

编辑:正如克里斯正确指出的那样,这将无法识别a.GetType()是否a属于已注册类型的子类。如果需要包含它,您将不得不遍历类型层次结构:

Action<object> action = null;
for (Type t = a.GetType(); t = t.BaseType; t != null) {
    if (typeActions.TryGetValue(t, out action)) {
        break;
    }
}
if (action != null) {
    action(a);
}

如果您需要涵盖泛型类型和/或接口,这也是可行的,但代码会变得越来越复杂。

于 2013-08-02T12:36:10.913 回答
0

我的解决方案与您的解决方案没有太大不同,但我是这样做的:

while(true){
    var typeOfVarToCheck = a.GetType();  // a comes from Op's Code
    if(typeOfVarToCheck==typeof(type1)){
        //Do Something
        break;
    }
    if(typeOfVarToCheck==typeof(type2)){
        //Do Something
        break;
    }
    //Do default
    break;
}
于 2013-08-02T12:28:46.203 回答
0

您应该将类​​型转换为字符串。

 var typeObj = //Value...

        switch (typeObj.GetType().ToString())
        {
            case "System.Int32":
                //Some Code
            case "System.String":
                //Some Code
            default:
                break;
        }
于 2013-08-02T12:40:57.850 回答