Используя Случай/Переключатель и GetType для определения объекта [дубликат]

counter=0
otherlist=[]
for element in mylist:
    if element == 0:
        otherlist[counter]="fail"
    else:
        otherlist[counter]="pass"
    counter += 1

Это не использует понимание, но это добьется цели. Надеюсь это поможет. Еще более быстрый вариант будет:

otherlist = []
for element in mylist:
    if element == 0:
        otherlist.append("fail")
    else:
        otherlist.append("pass")

Вы также можете разрешить 0 для представления False и 1 для представления True

otherlist = []
for element in mylist:
    if element == 0:
        otherlist.append(False)
    else:
        otherlist.append(True)
143
задан Community 23 May 2017 в 11:47
поделиться

8 ответов

Если я действительно имел к switch на типе объекта я использовал бы .ToString(). Однако я избежал бы его любой ценой: IDictionary<Type, int> сделает намного лучше, посетитель мог бы быть излишеством, но иначе это - все еще превосходное решение.

74
ответ дан 23 November 2019 в 22:59
поделиться

Я просто использовал бы если оператор. В этом случае:

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

Другой способ сделать это:

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

Первый пример верен для точных типов только, где последние проверки на наследование также.

24
ответ дан 23 November 2019 в 22:59
поделиться

Можно сделать это:

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

В то время как это было бы более изящно, это возможно не столь эффективно как некоторые из других ответов здесь.

12
ответ дан 23 November 2019 в 22:59
поделиться

Один подход должен добавить чистый виртуальный GetNodeType () метод к NodeDTO и переопределить его в потомках так, чтобы каждый потомок возвратил фактический тип.

7
ответ дан 23 November 2019 в 22:59
поделиться

В зависимости от того, что Вы делаете в операторе переключения, корректный ответ является полиморфизмом. Просто поместите виртуальную функцию в интерфейс/базовый класс и переопределение для каждого типа узла.

4
ответ дан 23 November 2019 в 22:59
поделиться

В сообщении блога 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; })
41
ответ дан 23 November 2019 в 22:59
поделиться

Я столкнулся с той же проблемой и наткнулся на это сообщение. Это то, что подразумевается под подходом 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;
    }
}

Есть ли еще одна реализация, которую я пропустил?

25
ответ дан 23 November 2019 в 22:59
поделиться

Вы можете сделать это:

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

Это ясно и просто. Это немного медленнее, чем кэшировать словарь где-то... но для большого количества кода это все равно не будет иметь значения...

9
ответ дан 23 November 2019 в 22:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: