Version Used:
Build of Visual Studio from the features/patterns branch as of 4th April 2016.
Steps to Reproduce:
1 Within a new solution, create a library project, TypeDeclarations, with the __DEMO_EXPERIMENTAL__ conditional compilation symbol set. Then create the following classes:
namespace TypeDeclarations
{
public class A
{
public int Prop1 { get; set; }
}
public class B
{
public static bool operator is(A a) => a.Prop1 == 0;
}
public class C
{
public int Prop2 { get; set; }
public static bool operator is(A a, out C c)
{
c = a.Prop1 != 0 ? new C { Prop2 = a.Prop1 } : null;
return a.Prop1 != 0;
}
}
public static class Patterns
{
public static int Pattern1(A a) => a is C(var c) ? c.Prop2 : 0;
public static int Pattern2(A a) =>
a match (
case C(var c) : c.Prop2
case B() : 0
);
}
}
2 Create another, cmdline, project, IsOperatorBugDemo, again with __DEMO_EXPERIMENTAL__ set. Create a main class, compile and run the code:
using System;
using TypeDeclarations;
namespace IsOperatorBugDemo
{
static class Program
{
static void Main()
{
Console.WriteLine(Patterns.Pattern1(new A()));
Console.WriteLine(Patterns.Pattern2(new A()));
Console.WriteLine(Patterns.Pattern1(new A { Prop1 = 1 }));
Console.WriteLine(Patterns.Pattern2(new A { Prop1 = 1 }));
Console.ReadLine();
}
}
}
3 Modify Program.cs in step 2 to the following and try to compile and run once more:
using System;
using TypeDeclarations;
namespace IsOperatorBugDemo
{
static class Program
{
static void Main()
{
Console.WriteLine(Pattern1(new A()));
Console.WriteLine(Pattern2(new A()));
Console.WriteLine(Pattern1(new A { Prop1 = 1 }));
Console.WriteLine(Pattern2(new A { Prop1 = 1 }));
Console.ReadLine();
}
private static int Pattern1(A a) => a is C(var c) ? c.Prop2 : 0;
private static int Pattern2(A a) =>
a match (
case C(var c) : c.Prop2
case B() : 0
);
}
}
Expected Behavior:
For both steps 2 and 3, the output should be:
0
0
1
1
Actual Behavior:
For step 2, the actual behaviour is as expected. For step 3, the IDE gives no "red squiggles" to indicate a problem, and the error list remains empty. The compilation fails though, with:
Program.cs(16,50,16,58): error CS8157: No 'operator is' declaration in 'C' was found with 1 out parameters
Program.cs(16,61,16,62): error CS0165: Use of unassigned local variable 'c'
Program.cs(20,22,20,30): error CS8157: No 'operator is' declaration in 'C' was found with 1 out parameters
Program.cs(21,22,21,25): error CS8157: No 'operator is' declaration in 'B' was found with 0 out parameters
Program.cs(20,35,20,40): error CS0428: Cannot convert method group 'Prop2' to non-delegate type 'int'. Did you intend to invoke the method?
@gafter, "Pattern matching is operator doesn't function correctly across assemblies" issue created as requested.
Thank you!
c#
return
(this.ReturnsVoid || this.ReturnType.SpecialType != SpecialType.System_Boolean) &&
!this.IsGenericMethod &&
!this.IsVararg &&
this.ParameterCount > 0 &&
!this.IsParams();
in PEMethodSymbol shouldn't this != be ==?
@orthoxerox,
No idea if that's the true fix or not. However, it certainly fixes the problem for me, which therefore let's me get on with experiments around stop-gap solutions of DUs and pattern matching if the former doesn't make it in to C# 7. So many thanks for that.
Fixed in the features/patterns branch by #10590
Most helpful comment
Fixed in the
features/patternsbranch by #10590