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)
Если я действительно имел к switch
на типе объекта я использовал бы .ToString()
. Однако я избежал бы его любой ценой: IDictionary<Type, int>
сделает намного лучше, посетитель мог бы быть излишеством, но иначе это - все еще превосходное решение.
Я просто использовал бы если оператор. В этом случае:
Type nodeType = node.GetType();
if (nodeType == typeof(CasusNodeDTO))
{
}
else ...
Другой способ сделать это:
if (node is CasusNodeDTO)
{
}
else ...
Первый пример верен для точных типов только, где последние проверки на наследование также.
Можно сделать это:
if (node is CasusNodeDTO)
{
...
}
else if (node is BucketNodeDTO)
{
...
}
...
В то время как это было бы более изящно, это возможно не столь эффективно как некоторые из других ответов здесь.
Один подход должен добавить чистый виртуальный GetNodeType () метод к NodeDTO и переопределить его в потомках так, чтобы каждый потомок возвратил фактический тип.
В зависимости от того, что Вы делаете в операторе переключения, корректный ответ является полиморфизмом. Просто поместите виртуальную функцию в интерфейс/базовый класс и переопределение для каждого типа узла.
В сообщении блога 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; })
Я столкнулся с той же проблемой и наткнулся на это сообщение. Это то, что подразумевается под подходом 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;
}
}
Есть ли еще одна реализация, которую я пропустил?
Вы можете сделать это:
function void PrintType(Type t) {
var t = true;
new Dictionary<Type, Action>{
{typeof(bool), () => Console.WriteLine("bool")},
{typeof(int), () => Console.WriteLine("int")}
}[t.GetType()]();
}
Это ясно и просто. Это немного медленнее, чем кэшировать словарь где-то... но для большого количества кода это все равно не будет иметь значения...