<强>可能重复:结果    C# - 有没有更好的替代比这为“上型开关”?

如果您想switch一个类型的对象,什么是做到这一点的最好方法是什么?

代码段

private int GetNodeType(NodeDTO node)
{
    switch (node.GetType())
    { 
        case typeof(CasusNodeDTO):
            return 1;
        case typeof(BucketNodeDTO):
            return 3;
        case typeof(BranchNodeDTO):
            return 0;
        case typeof(LeafNodeDTO):
            return 2;
        default:
            return -1;
    }
}

我知道这不工作的方式,但我不知道你怎么能解决这个问题。 是if/else声明适当在这种情况下?

或者你使用的开关,并添加.ToString()的类型?

有帮助吗?

解决方案

如果我的真正的不得不switch对类型的对象,我会使用.ToString()。不过,我会避免不惜一切代价:IDictionary<Type, int>会做的更好,游客可能是矫枉过正但否则它仍然是一个完全没有问题的解决方案。

其他提示

只要你想在自己的用户定义类型转换这不会直接解决您的问题,但对于其他人的利益谁只想打开内置类型,可以使用的类型码枚举:

switch (Type.GetTypeCode(node.GetType()))
{
    case TypeCode.Decimal:
        // Handle Decimal
        break;

    case TypeCode.Int32:
        // Handle Int32
        break;
     ...
}

在MSDN博客文章的 许多问题:开关上型 是为什么 .NET 不提供某些信息接通的类型。

像往常一样 - 解决方法总是存在

这一个不是我的,但不幸的是我已经失去了所述源。这使得对各类可能的开关,但我个人认为这是相当尴尬(字典的想法是更好):

  public class Switch
  {
      public Switch(Object o)
      {
          Object = o;
      }

      public Object Object { get; private set; }
  }


  /// <summary>
  /// Extensions, because otherwise casing fails on Switch==null
  /// </summary>
  public static class SwitchExtensions
  {
      public static Switch Case<T>(this Switch s, Action<T> a)
            where T : class
      {
          return Case(s, o => true, a, false);
      }

      public static Switch Case<T>(this Switch s, Action<T> a,
           bool fallThrough) where T : class
      {
          return Case(s, o => true, a, fallThrough);
      }

      public static Switch Case<T>(this Switch s,
          Func<T, bool> c, Action<T> a) where T : class
      {
          return Case(s, c, a, false);
      }

      public static Switch Case<T>(this Switch s,
          Func<T, bool> c, Action<T> a, bool fallThrough) where T : class
      {
          if (s == null)
          {
              return null;
          }

          T t = s.Object as T;
          if (t != null)
          {
              if (c(t))
              {
                  a(t);
                  return fallThrough ? s : null;
              }
          }

          return s;
      }
  }

用法:

 new Switch(foo)
     .Case<Fizz>
         (action => { doingSomething = FirstMethodCall(); })
     .Case<Buzz>
         (action => { return false; })

我只是使用if语句。在这种情况下:

Type nodeType = node.GetType();
if (nodeType == typeof(CasusNodeDTO))
{
}
else ... 

在其他的方法来做到这是:

if (node is CasusNodeDTO)
{
}
else ...

在第一个例子是真对确切类型只,其中对于继承后者检查过。

我面临着同样的问题,碰到这个岗位来了。 这是什么年代由IDictionary的方法意味着:

Dictionary<Type, int> typeDict = new Dictionary<Type, int>
{
    {typeof(int),0},
    {typeof(string),1},
    {typeof(MyClass),2}
};

void Foo(object o)
{
    switch (typeDict[o.GetType()])
    {
        case 0:
            Print("I'm a number.");
            break;
        case 1:
            Print("I'm a text.");
            break;
        case 2:
            Print("I'm classy.");
            break;
        default:
            break;
    }
}

如果是这样,我不能说我在与case语句字典调和数的粉丝。

这将是理想的,但字典参考杀死它:

void FantasyFoo(object o)
{
    switch (typeDict[o.GetType()])
    {
        case typeDict[typeof(int)]:
            Print("I'm a number.");
            break;
        case typeDict[typeof(string)]:
            Print("I'm a text.");
            break;
        case typeDict[typeof(MyClass)]:
            Print("I'm classy.");
            break;
        default:
            break;
    }
}

是否有我忽视了另一种实现方式?

您可以这样做:

if (node is CasusNodeDTO)
{
    ...
}
else if (node is BucketNodeDTO)
{
    ...
}
...

虽然这将是更优雅,它可能不一样有效,这里的一些其他的答案。

您可以这样做:

function void PrintType(Type t) {
 var t = true;
 new Dictionary<Type, Action>{
   {typeof(bool), () => Console.WriteLine("bool")},
   {typeof(int),  () => Console.WriteLine("int")}
 }[t.GetType()]();
}

很显然和它的方便。 它不是某个缓存字典有点慢..但对于大量的代码,这将不会怎样都无所谓..

一种方法是一个纯虚拟GetNodeType()方法添加到NodeDTO和使得每个后代返回实际类型覆盖它在后代。

根据您的switch语句在做什么,正确答案是多态性。只要把一个虚拟函数的接口/基类并覆盖每个节点类型。

其实我更喜欢给出如下答案的方法: 有没有更好的替代比此为 '开关型'?

有然而是关于如C#面向对象的语言不执行任何类型的比较methids良好的论点。你可以作为替代延伸,并且使用继承添加额外的所需的功能。

这点是在作者的博客中的评论讨论: 的http://博客。 msdn.com/b/jaredpar/archive/2008/05/16/switching-on-types.aspx#8553535

我发现这一个非常有趣的点,这改变了我的做法,类似的情况,只是希望这可以帮助别人。

此致韦恩

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top