示例#1
0
        public void CS0472WRN_NubExprIsConstBool()
        {
            // Due to a long-standing bug, the native compiler does not produce warnings for "guid == null",
            // but does for "int == null". Roslyn corrects this lapse and produces warnings for both built-in
            // and user-defined lifted equality operators, but the new warnings for user-defined types are
            // only given in "strict" more.

            var text = @"
using System;
class MyClass
{
    public static void W(bool b)
    {
        System.Console.Write(b ? 't' : 'f');
    }

    enum E : int { };

    public static void Main()
    {
        Guid g = default(Guid);
        Guid? h = g;
        int i = 0;
        int? n = i;

        W(i == null);            // CS0472
        W(i != null);            // CS0472
        W(n == null);            // no error
        W(n != null);            // no error
        W(g == null);            // CS0472
        W(g != null);            // CS0472
        W(h == null);            // no error
        W(h != null);            // no error

        W(i == default(short?));            // CS0472
        W(i != default(short?));            // CS0472
        W(n == default(short?));            // no error
        W(n != default(short?));            // no error
        W(g == default(Guid?));             // CS0472
        W(g != default(Guid?));             // CS0472
        W(h == default(Guid?));             // no error
        W(h != default(Guid?));             // no error

        W(i == new sbyte?());            // CS0472
        W(i != new sbyte?());            // CS0472
        W(n == new sbyte?());            // no error
        W(n != new sbyte?());            // no error
        W(g == new Guid?());             // CS0472
        W(g != new Guid?());             // CS0472
        W(h == new Guid?());             // no error
        W(h != new Guid?());             // no error

        System.Console.WriteLine();


        W(null == i);            // CS0472
        W(null != i);            // CS0472
        W(null == n);            // no error
        W(null != n);            // no error
        W(null == g);            // CS0472
        W(null != g);            // CS0472
        W(null == h);            // no error
        W(null != h);            // no error

        W(default(long?) == i);            // CS0472
        W(default(long?) != i);            // CS0472
        W(default(long?) == n);            // no error
        W(default(long?) != n);            // no error
        W(default(Guid?) == g);            // CS0472
        W(default(Guid?) != g);            // CS0472
        W(default(Guid?) == h);            // no error
        W(default(Guid?) != h);            // no error

        W(new double?() == i);            // CS0472
        W(new double?() != i);            // CS0472
        W(new double?() == n);            // no error
        W(new double?() != n);            // no error
        W(new Guid?() == g);              // CS0472
        W(new Guid?() != g);              // CS0472
        W(new Guid?() == h);              // no error
        W(new Guid?() != h);              // no error

        System.Console.WriteLine();

        W(null == null);                  // No error, because both sides are nullable, but of course
        W(null != null);                  // we could give a warning here as well.

        System.Console.WriteLine();

        //check comparisons with converted constants
        W((E?)1 == null);
        W(null != (E?)1);

        W((int?)1 == null);
        W(null != (int?)1);

        //check comparisons when null is converted 

        W(0 == (int?)null);
        W((int?)null != 0);
 
        W(0 == (E?)null);
        W((E?)null != 0);
    }
}
";

            string expected = @"ftftftftftftftftftftftft
ftftftftftftftftftftftft
tf
ftftftft";
            var fullExpected = new DiagnosticDescription[] {
                // (19,11): warning CS0472: The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type 'int?'
                //         W(i == null);            // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool, "i == null").WithArguments("false", "int", "int?").WithLocation(19, 11),
                // (20,11): warning CS0472: The result of the expression is always 'true' since a value of type 'int' is never equal to 'null' of type 'int?'
                //         W(i != null);            // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool, "i != null").WithArguments("true", "int", "int?").WithLocation(20, 11),
                // (23,11): warning CS8073: The result of the expression is always 'false' since a value of type 'System.Guid' is never equal to 'null' of type 'System.Guid?'
                //         W(g == null);            // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool2, "g == null").WithArguments("false", "System.Guid", "System.Guid?").WithLocation(23, 11),
                // (24,11): warning CS8073: The result of the expression is always 'true' since a value of type 'System.Guid' is never equal to 'null' of type 'System.Guid?'
                //         W(g != null);            // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool2, "g != null").WithArguments("true", "System.Guid", "System.Guid?").WithLocation(24, 11),
                // (28,11): warning CS0472: The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type 'short?'
                //         W(i == default(short?));            // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool, "i == default(short?)").WithArguments("false", "int", "short?").WithLocation(28, 11),
                // (29,11): warning CS0472: The result of the expression is always 'true' since a value of type 'int' is never equal to 'null' of type 'short?'
                //         W(i != default(short?));            // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool, "i != default(short?)").WithArguments("true", "int", "short?").WithLocation(29, 11),
                // (32,11): warning CS8073: The result of the expression is always 'false' since a value of type 'System.Guid' is never equal to 'null' of type 'System.Guid?'
                //         W(g == default(Guid?));             // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool2, "g == default(Guid?)").WithArguments("false", "System.Guid", "System.Guid?").WithLocation(32, 11),
                // (33,11): warning CS8073: The result of the expression is always 'true' since a value of type 'System.Guid' is never equal to 'null' of type 'System.Guid?'
                //         W(g != default(Guid?));             // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool2, "g != default(Guid?)").WithArguments("true", "System.Guid", "System.Guid?").WithLocation(33, 11),
                // (37,11): warning CS0472: The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type 'sbyte?'
                //         W(i == new sbyte?());            // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool, "i == new sbyte?()").WithArguments("false", "int", "sbyte?").WithLocation(37, 11),
                // (38,11): warning CS0472: The result of the expression is always 'true' since a value of type 'int' is never equal to 'null' of type 'sbyte?'
                //         W(i != new sbyte?());            // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool, "i != new sbyte?()").WithArguments("true", "int", "sbyte?").WithLocation(38, 11),
                // (41,11): warning CS8073: The result of the expression is always 'false' since a value of type 'System.Guid' is never equal to 'null' of type 'System.Guid?'
                //         W(g == new Guid?());             // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool2, "g == new Guid?()").WithArguments("false", "System.Guid", "System.Guid?").WithLocation(41, 11),
                // (42,11): warning CS8073: The result of the expression is always 'true' since a value of type 'System.Guid' is never equal to 'null' of type 'System.Guid?'
                //         W(g != new Guid?());             // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool2, "g != new Guid?()").WithArguments("true", "System.Guid", "System.Guid?").WithLocation(42, 11),
                // (49,11): warning CS0472: The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type 'int?'
                //         W(null == i);            // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool, "null == i").WithArguments("false", "int", "int?").WithLocation(49, 11),
                // (50,11): warning CS0472: The result of the expression is always 'true' since a value of type 'int' is never equal to 'null' of type 'int?'
                //         W(null != i);            // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool, "null != i").WithArguments("true", "int", "int?").WithLocation(50, 11),
                // (53,11): warning CS8073: The result of the expression is always 'false' since a value of type 'System.Guid' is never equal to 'null' of type 'System.Guid?'
                //         W(null == g);            // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool2, "null == g").WithArguments("false", "System.Guid", "System.Guid?").WithLocation(53, 11),
                // (54,11): warning CS8073: The result of the expression is always 'true' since a value of type 'System.Guid' is never equal to 'null' of type 'System.Guid?'
                //         W(null != g);            // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool2, "null != g").WithArguments("true", "System.Guid", "System.Guid?").WithLocation(54, 11),
                // (58,11): warning CS0472: The result of the expression is always 'false' since a value of type 'long' is never equal to 'null' of type 'long?'
                //         W(default(long?) == i);            // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool, "default(long?) == i").WithArguments("false", "long", "long?").WithLocation(58, 11),
                // (59,11): warning CS0472: The result of the expression is always 'true' since a value of type 'long' is never equal to 'null' of type 'long?'
                //         W(default(long?) != i);            // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool, "default(long?) != i").WithArguments("true", "long", "long?").WithLocation(59, 11),
                // (62,11): warning CS8073: The result of the expression is always 'false' since a value of type 'System.Guid' is never equal to 'null' of type 'System.Guid?'
                //         W(default(Guid?) == g);            // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool2, "default(Guid?) == g").WithArguments("false", "System.Guid", "System.Guid?").WithLocation(62, 11),
                // (63,11): warning CS8073: The result of the expression is always 'true' since a value of type 'System.Guid' is never equal to 'null' of type 'System.Guid?'
                //         W(default(Guid?) != g);            // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool2, "default(Guid?) != g").WithArguments("true", "System.Guid", "System.Guid?").WithLocation(63, 11),
                // (67,11): warning CS0472: The result of the expression is always 'false' since a value of type 'double' is never equal to 'null' of type 'double?'
                //         W(new double?() == i);            // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool, "new double?() == i").WithArguments("false", "double", "double?").WithLocation(67, 11),
                // (68,11): warning CS0472: The result of the expression is always 'true' since a value of type 'double' is never equal to 'null' of type 'double?'
                //         W(new double?() != i);            // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool, "new double?() != i").WithArguments("true", "double", "double?").WithLocation(68, 11),
                // (71,11): warning CS8073: The result of the expression is always 'false' since a value of type 'System.Guid' is never equal to 'null' of type 'System.Guid?'
                //         W(new Guid?() == g);              // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool2, "new Guid?() == g").WithArguments("false", "System.Guid", "System.Guid?").WithLocation(71, 11),
                // (72,11): warning CS8073: The result of the expression is always 'true' since a value of type 'System.Guid' is never equal to 'null' of type 'System.Guid?'
                //         W(new Guid?() != g);              // CS0472
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool2, "new Guid?() != g").WithArguments("true", "System.Guid", "System.Guid?").WithLocation(72, 11),
                // (84,11): warning CS0472: The result of the expression is always 'false' since a value of type 'MyClass.E' is never equal to 'null' of type 'MyClass.E?'
                //         W((E?)1 == null);
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool, "(E?)1 == null").WithArguments("false", "MyClass.E", "MyClass.E?").WithLocation(84, 11),
                // (85,11): warning CS0472: The result of the expression is always 'true' since a value of type 'MyClass.E' is never equal to 'null' of type 'MyClass.E?'
                //         W(null != (E?)1);
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool, "null != (E?)1").WithArguments("true", "MyClass.E", "MyClass.E?").WithLocation(85, 11),
                // (87,11): warning CS0472: The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type 'int?'
                //         W((int?)1 == null);
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool, "(int?)1 == null").WithArguments("false", "int", "int?").WithLocation(87, 11),
                // (88,11): warning CS0472: The result of the expression is always 'true' since a value of type 'int' is never equal to 'null' of type 'int?'
                //         W(null != (int?)1);
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool, "null != (int?)1").WithArguments("true", "int", "int?").WithLocation(88, 11),
                // (92,11): warning CS0472: The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type 'int?'
                //         W(0 == (int?)null);
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool, "0 == (int?)null").WithArguments("false", "int", "int?").WithLocation(92, 11),
                // (93,11): warning CS0472: The result of the expression is always 'true' since a value of type 'int' is never equal to 'null' of type 'int?'
                //         W((int?)null != 0);
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool, "(int?)null != 0").WithArguments("true", "int", "int?").WithLocation(93, 11),
                // (95,11): warning CS0472: The result of the expression is always 'false' since a value of type 'MyClass.E' is never equal to 'null' of type 'MyClass.E?'
                //         W(0 == (E?)null);
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool, "0 == (E?)null").WithArguments("false", "MyClass.E", "MyClass.E?").WithLocation(95, 11),
                // (96,11): warning CS0472: The result of the expression is always 'true' since a value of type 'MyClass.E' is never equal to 'null' of type 'MyClass.E?'
                //         W((E?)null != 0);
                Diagnostic(ErrorCode.WRN_NubExprIsConstBool, "(E?)null != 0").WithArguments("true", "MyClass.E", "MyClass.E?").WithLocation(96, 11)
            };
            var compatibleExpected = fullExpected.Where(d => !d.Code.Equals((int)ErrorCode.WRN_NubExprIsConstBool2)).ToArray();
            this.CompileAndVerify(source: text, expectedOutput: expected).VerifyDiagnostics(compatibleExpected);
            this.CompileAndVerify(source: text, expectedOutput: expected, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular.WithStrictFeature()).VerifyDiagnostics(fullExpected);
        }