using System; namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty { public class PatternMatching { public void SimpleTypePattern(object x) { if (x is string value) { Console.WriteLine(value); } } public void TypePatternWithShortcircuit(object x) { Use(F() && x is string text && text.Contains("a")); if (F() && x is string text2 && text2.Contains("a")) { Console.WriteLine(text2); } } public void TypePatternWithShortcircuitAnd(object x) { if (x is string text && text.Contains("a")) { Console.WriteLine(text); } else { Console.WriteLine(); } } public void TypePatternWithShortcircuitOr(object x) { if (!(x is string text) || text.Contains("a")) { Console.WriteLine(); } else { Console.WriteLine(text); } } public void TypePatternWithShortcircuitOr2(object x) { if (F() || !(x is string value)) { Console.WriteLine(); } else { Console.WriteLine(value); } } public void TypePatternValueTypesCondition(object x) { if (x is int num) { Console.WriteLine("Integer: " + num); } else { Console.WriteLine("else"); } } public void TypePatternValueTypesCondition2() { if (GetObject() is int num) { Console.WriteLine("Integer: " + num); } else { Console.WriteLine("else"); } } public void TypePatternValueTypesWithShortcircuitAnd(object x) { if (x is int num && num.GetHashCode() > 0) { Console.WriteLine("Positive integer: " + num); } else { Console.WriteLine("else"); } } public void TypePatternValueTypesWithShortcircuitOr(object x) { if (!(x is int value) || value.GetHashCode() > 0) { Console.WriteLine(); } else { Console.WriteLine(value); } } #if ROSLYN3 || OPT // Roslyn 2.x generates a complex infeasible path in debug builds, which RemoveInfeasiblePathTransform // currently cannot handle. Because this would increase the complexity of that transform, we ignore // this case. public void TypePatternValueTypesWithShortcircuitOr2(object x) { if (F() || !(x is int value)) { Console.WriteLine(); } else { Console.WriteLine(value); } } #endif public void TypePatternGenerics(object x) { if (x is T val) { Console.WriteLine(val.GetType().FullName); } else { Console.WriteLine("not a " + typeof(T).FullName); } } public void TypePatternGenericRefType(object x) where T : class { if (x is T val) { Console.WriteLine(val.GetType().FullName); } else { Console.WriteLine("not a " + typeof(T).FullName); } } public void TypePatternGenericValType(object x) where T : struct { if (x is T val) { Console.WriteLine(val.GetType().FullName); } else { Console.WriteLine("not a " + typeof(T).FullName); } } public void TypePatternValueTypesWithShortcircuitAndMultiUse(object x) { if (x is int num && num.GetHashCode() > 0 && num % 2 == 0) { Console.WriteLine("Positive integer: " + num); } else { Console.WriteLine("else"); } } public void TypePatternValueTypesWithShortcircuitAndMultiUse2(object x) { if ((x is int num && num.GetHashCode() > 0 && num % 2 == 0) || F()) { Console.WriteLine("true"); } else { Console.WriteLine("else"); } } public void TypePatternValueTypesWithShortcircuitAndMultiUse3(object x) { if (F() || (x is int num && num.GetHashCode() > 0 && num % 2 == 0)) { Console.WriteLine("true"); } else { Console.WriteLine("else"); } } public void TypePatternValueTypes() { Use(F() && GetObject() is int num && num.GetHashCode() > 0 && num % 2 == 0); } public static void NotTypePatternVariableUsedOutsideTrueBranch(object x) { string text = x as string; if (text != null && text.Length > 5) { Console.WriteLine("pattern matches"); } if (text != null && text.Length > 10) { Console.WriteLine("other use!"); } } public static void NotTypePatternBecauseVarIsNotDefAssignedInCaseOfFallthrough(object x) { #if OPT string obj = x as string; if (obj == null) { Console.WriteLine("pattern doesn't match"); } Console.WriteLine(obj == null); #else string text = x as string; if (text == null) { Console.WriteLine("pattern doesn't match"); } Console.WriteLine(text == null); #endif } private bool F() { return true; } private object GetObject() { throw new NotImplementedException(); } private void Use(bool x) { } } }