PageRenderTime 25ms CodeModel.GetById 2ms app.highlight 16ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Compilers/CSharp/Test/Semantic/Semantics/ConditionalOperatorTests.cs

https://github.com/EkardNT/Roslyn
C# | 1257 lines | 1175 code | 48 blank | 34 comment | 3 complexity | 2d247a2894f23ebab6869b35c1a1dfef MD5 | raw file
   1// Copyright (c) Microsoft Open Technologies, Inc.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
   2
   3using System.Linq;
   4using Microsoft.CodeAnalysis.CSharp.Symbols;
   5using Microsoft.CodeAnalysis.CSharp.Syntax;
   6using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
   7using Microsoft.CodeAnalysis.Test.Utilities;
   8using Roslyn.Test.Utilities;
   9using Xunit;
  10
  11namespace Microsoft.CodeAnalysis.CSharp.UnitTests
  12{
  13    /// <summary>
  14    /// Test binding of the conditional (aka ternary) operator.
  15    /// </summary>
  16    public class ConditionalOperatorTests : CSharpTestBase
  17    {
  18        /// <summary>
  19        /// Both branches have the same type, so no conversion is necessary.
  20        /// </summary>
  21        [Fact]
  22        public void TestSameType()
  23        {
  24            TestConditional("true ? 1 : 2", expectedType: "System.Int32");
  25            TestConditional("false ? 'a' : 'b'", expectedType: "System.Char");
  26            TestConditional("true ? 1.5 : GetDouble()", expectedType: "System.Double");
  27            TestConditional("false ? GetObject() : GetObject()", expectedType: "System.Object");
  28            TestConditional("true ? GetUserGeneric<T>() : GetUserGeneric<T>()", expectedType: "D<T>");
  29            TestConditional("false ? GetTypeParameter<T>() : GetTypeParameter<T>()", expectedType: "T");
  30        }
  31
  32        /// <summary>
  33        /// Both branches have types and exactly one expression is convertible to the type of the other.
  34        /// </summary>
  35        [Fact]
  36        public void TestOneConversion()
  37        {
  38            TestConditional("true ? GetShort() : GetInt()", expectedType: "System.Int32");
  39            TestConditional("false ? \"string\" : GetObject()", expectedType: "System.Object");
  40            TestConditional("true ? GetVariantInterface<string, int>() : GetVariantInterface<object, int>()", expectedType: "I<System.String, System.Int32>");
  41            TestConditional("false ? GetVariantInterface<int, object>() : GetVariantInterface<int, string>()", expectedType: "I<System.Int32, System.Object>");
  42        }
  43
  44        /// <summary>
  45        /// Both branches have types and both expression are convertible to the type of the other.
  46        /// The wider type is preferred.
  47        /// </summary>
  48        /// <remarks>
  49        /// Cases where both conversions are possible and neither is preferred as the
  50        /// wider of the two are possible only in the presence of user-defined implicit
  51        /// conversions.  Such cases are tested separately.  
  52        /// See SemanticErrorTests.CS0172ERR_AmbigQM.
  53        /// </remarks>
  54        [Fact]
  55        public void TestAmbiguousPreferWider()
  56        {
  57            TestConditional("true ? 1 : (short)2", expectedType: "System.Int32");
  58            TestConditional("false ? (float)2 : 1", expectedType: "System.Single");
  59            TestConditional("true ? 1.5d : (double)2", expectedType: "System.Double");
  60        }
  61
  62        /// <summary>
  63        /// Both branches have types but neither expression is convertible to the type
  64        /// of the other.
  65        /// </summary>
  66        [Fact]
  67        public void TestNoConversion()
  68        {
  69            TestConditional("true ? T : U", null,
  70                Diagnostic(ErrorCode.ERR_BadSKunknown, "T").WithArguments("T", "type"),
  71                Diagnostic(ErrorCode.ERR_BadSKunknown, "U").WithArguments("U", "type"),
  72                Diagnostic(ErrorCode.ERR_InvalidQM, "true ? T : U").WithArguments("T", "U"));
  73            TestConditional("false ? T : 1", null,
  74                Diagnostic(ErrorCode.ERR_BadSKunknown, "T").WithArguments("T", "type"),
  75                Diagnostic(ErrorCode.ERR_InvalidQM, "false ? T : 1").WithArguments("T", "int"));
  76            TestConditional("true ? GetUserGeneric<char>() : GetUserNonGeneric()", null,
  77                Diagnostic(ErrorCode.ERR_InvalidQM, "true ? GetUserGeneric<char>() : GetUserNonGeneric()").WithArguments("D<char>", "C"));
  78        }
  79
  80        /// <summary>
  81        /// Exactly one branch has a type and the other expression is convertible to that type.
  82        /// </summary>
  83        [Fact]
  84        public void TestOneUntypedSuccess()
  85        {
  86            TestConditional("true ? GetObject() : null", expectedType: "System.Object"); //null literal
  87            TestConditional("false ? GetString : (System.Func<string>)null", expectedType: "System.Func<System.String>"); //method group
  88            TestConditional("true ? (System.Func<int, int>)null : x => x", expectedType: "System.Func<System.Int32, System.Int32>"); //lambda
  89        }
  90
  91        /// <summary>
  92        /// Exactly one branch has a type but the other expression is not convertible to that type.
  93        /// </summary>
  94        [Fact]
  95        public void TestOneUntypedFailure()
  96        {
  97            TestConditional("true ? GetInt() : null", null,
  98                Diagnostic(ErrorCode.ERR_InvalidQM, "true ? GetInt() : null").WithArguments("int", "<null>"));
  99            TestConditional("false ? GetString : (System.Func<int>)null", null,
 100                Diagnostic(ErrorCode.ERR_BadRetType, "GetString").WithArguments("C.GetString()", "string"));
 101            TestConditional("true ? (System.Func<int, short>)null : x => x", null,
 102                Diagnostic(ErrorCode.ERR_InvalidQM, "true ? (System.Func<int, short>)null : x => x").WithArguments("System.Func<int, short>", "lambda expression"));
 103        }
 104
 105        [Fact]
 106        public void TestBothUntyped()
 107        {
 108            TestConditional("true ? null : null", null,
 109                Diagnostic(ErrorCode.ERR_InvalidQM, "true ? null : null").WithArguments("<null>", "<null>"));
 110            TestConditional("false ? null : GetInt", null,
 111                Diagnostic(ErrorCode.ERR_InvalidQM, "false ? null : GetInt").WithArguments("<null>", "method group"));
 112            TestConditional("true ? null : x => x", null,
 113                Diagnostic(ErrorCode.ERR_InvalidQM, "true ? null : x => x").WithArguments("<null>", "lambda expression"));
 114
 115            TestConditional("false ? GetInt : GetInt", null,
 116                Diagnostic(ErrorCode.ERR_InvalidQM, "false ? GetInt : GetInt").WithArguments("method group", "method group"));
 117            TestConditional("true ? GetInt : x => x", null,
 118                Diagnostic(ErrorCode.ERR_InvalidQM, "true ? GetInt : x => x").WithArguments("method group", "lambda expression"));
 119
 120            TestConditional("false ? x => x : x => x", null,
 121                Diagnostic(ErrorCode.ERR_InvalidQM, "false ? x => x : x => x").WithArguments("lambda expression", "lambda expression"));
 122        }
 123
 124        [Fact]
 125        public void TestFunCall()
 126        {
 127            TestConditional("true ? GetVoid() : GetInt()", null,
 128                Diagnostic(ErrorCode.ERR_InvalidQM, "true ? GetVoid() : GetInt()").WithArguments("void", "int"));
 129            TestConditional("GetVoid() ? 1 : 2", null,
 130                Diagnostic(ErrorCode.ERR_NoImplicitConv, "GetVoid()").WithArguments("void", "bool"));
 131            TestConditional("GetInt() ? 1 : 2", null,
 132                Diagnostic(ErrorCode.ERR_NoImplicitConv, "GetInt()").WithArguments("int", "bool"));
 133            TestConditional("GetBool() ? 1 : 2", "System.Int32");
 134        }
 135
 136        [Fact]
 137        public void TestEmptyExpression()
 138        {
 139            TestConditional("true ?  : GetInt()", null,
 140                Diagnostic(ErrorCode.ERR_InvalidExprTerm, ":").WithArguments(":"));
 141            TestConditional("true ? GetInt() :  ", null,
 142                Diagnostic(ErrorCode.ERR_InvalidExprTerm, ")").WithArguments(")"));
 143        }
 144
 145        [Fact]
 146        public void TestEnum()
 147        {
 148            TestConditional("true? 0 : color.Blue", "color");
 149            TestConditional("true? 5 : color.Blue", null,
 150                Diagnostic(ErrorCode.ERR_InvalidQM, "true? 5 : color.Blue").WithArguments("int", "color"));
 151            TestConditional("true? null : color.Blue", null,
 152                Diagnostic(ErrorCode.ERR_InvalidQM, "true? null : color.Blue").WithArguments("<null>", "color"));
 153        }
 154
 155        [Fact]
 156        public void TestAs()
 157        {
 158            TestConditional(@"(1 < 2) ? ""MyString"" as string : "" """, "System.String");
 159            TestConditional(@"(1 > 2) ? "" "" : ""MyString"" as string", "System.String");
 160        }
 161
 162        [Fact]
 163        public void TestGeneric()
 164        {
 165            TestConditional(@"GetUserNonGeneric()? 1 : 2", null, Diagnostic(ErrorCode.ERR_NoImplicitConv, "GetUserNonGeneric()").WithArguments("C", "bool"));
 166            TestConditional(@"GetUserGeneric<T>()? 1 : 2", null, Diagnostic(ErrorCode.ERR_NoImplicitConv, "GetUserGeneric<T>()").WithArguments("D<T>", "bool"));
 167            TestConditional(@"GetTypeParameter<T>()? 1 : 2", null, Diagnostic(ErrorCode.ERR_NoImplicitConv, "GetTypeParameter<T>()").WithArguments("T", "bool"));
 168            TestConditional(@"GetVariantInterface<T, U>()? 1 : 2", null, Diagnostic(ErrorCode.ERR_NoImplicitConv, "GetVariantInterface<T, U>()").WithArguments("I<T, U>", "bool"));
 169        }
 170
 171        [Fact]
 172        public void TestInvalidCondition()
 173        {
 174            // CONSIDER: dev10 reports ERR_ConstOutOfRange
 175            TestConditional("1 ? 2 : 3", null,
 176                Diagnostic(ErrorCode.ERR_NoImplicitConv, "1").WithArguments("int", "bool"));
 177
 178            TestConditional("foo ? 'a' : 'b'", null,
 179                Diagnostic(ErrorCode.ERR_NameNotInContext, "foo").WithArguments("foo"));
 180
 181            TestConditional("new Foo() ? GetObject() : null", null,
 182                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "Foo").WithArguments("Foo"));
 183
 184            // CONSIDER: dev10 reports ERR_ConstOutOfRange
 185            TestConditional("1 ? null : null", null,
 186                Diagnostic(ErrorCode.ERR_NoImplicitConv, "1").WithArguments("int", "bool"),
 187                Diagnostic(ErrorCode.ERR_InvalidQM, "1 ? null : null").WithArguments("<null>", "<null>"));
 188        }
 189
 190        [WorkItem(545408, "DevDiv")]
 191        [Fact]
 192        public void TestDelegateCovarianceConversions()
 193        {
 194            var source = @"
 195using System;
 196using System.Collections.Generic;
 197
 198delegate void D<out T>();
 199
 200class Base { }
 201class Derived : Base { }
 202
 203class Program
 204{
 205    static void Main()
 206    {
 207        bool testFlag = true;
 208
 209        D<Base> baseDelegate = () => Console.WriteLine(""B"");
 210        D<Derived> derivedDelegate = () => Console.WriteLine(""D"");
 211
 212        D<Base> fcn;
 213        
 214        fcn = testFlag ? baseDelegate : derivedDelegate;
 215        fcn();
 216
 217        fcn = testFlag ? derivedDelegate : baseDelegate;
 218        fcn();
 219
 220        fcn = baseDelegate ?? derivedDelegate;
 221        fcn();
 222
 223        fcn = derivedDelegate ?? baseDelegate;
 224        fcn();
 225
 226        IEnumerable<Base> baseSequence = null;
 227        List<Derived> derivedList = null;
 228        IEnumerable<Base> result = testFlag ? baseSequence : derivedList;
 229
 230    }
 231}
 232";
 233
 234            string expectedOutput = @"B
 235D
 236B
 237D";
 238
 239            // Note the castclass instructions:
 240            string expectedIL = @"
 241{
 242  // Code size      128 (0x80)
 243  .maxstack  2
 244  .locals init (bool V_0, //testFlag
 245  D<Base> V_1, //baseDelegate
 246  D<Derived> V_2, //derivedDelegate
 247  System.Collections.Generic.IEnumerable<Base> V_3, //baseSequence
 248  System.Collections.Generic.List<Derived> V_4, //derivedList
 249  D<Base> V_5)
 250  IL_0000:  ldc.i4.1
 251  IL_0001:  stloc.0
 252  IL_0002:  ldsfld     ""D<Base> Program.CS$<>9__CachedAnonymousMethodDelegate1""
 253  IL_0007:  dup
 254  IL_0008:  brtrue.s   IL_001d
 255  IL_000a:  pop
 256  IL_000b:  ldnull
 257  IL_000c:  ldftn      ""void Program.<Main>b__0(object)""
 258  IL_0012:  newobj     ""D<Base>..ctor(object, System.IntPtr)""
 259  IL_0017:  dup
 260  IL_0018:  stsfld     ""D<Base> Program.CS$<>9__CachedAnonymousMethodDelegate1""
 261  IL_001d:  stloc.1
 262  IL_001e:  ldsfld     ""D<Derived> Program.CS$<>9__CachedAnonymousMethodDelegate3""
 263  IL_0023:  dup
 264  IL_0024:  brtrue.s   IL_0039
 265  IL_0026:  pop
 266  IL_0027:  ldnull
 267  IL_0028:  ldftn      ""void Program.<Main>b__2(object)""
 268  IL_002e:  newobj     ""D<Derived>..ctor(object, System.IntPtr)""
 269  IL_0033:  dup
 270  IL_0034:  stsfld     ""D<Derived> Program.CS$<>9__CachedAnonymousMethodDelegate3""
 271  IL_0039:  stloc.2
 272  IL_003a:  ldloc.0
 273  IL_003b:  brtrue.s   IL_0044
 274  IL_003d:  ldloc.2
 275  IL_003e:  stloc.s    V_5
 276  IL_0040:  ldloc.s    V_5
 277  IL_0042:  br.s       IL_0045
 278  IL_0044:  ldloc.1
 279  IL_0045:  callvirt   ""void D<Base>.Invoke()""
 280  IL_004a:  ldloc.0
 281  IL_004b:  brtrue.s   IL_0050
 282  IL_004d:  ldloc.1
 283  IL_004e:  br.s       IL_0055
 284  IL_0050:  ldloc.2
 285  IL_0051:  stloc.s    V_5
 286  IL_0053:  ldloc.s    V_5
 287  IL_0055:  callvirt   ""void D<Base>.Invoke()""
 288  IL_005a:  ldloc.1
 289  IL_005b:  dup
 290  IL_005c:  brtrue.s   IL_0064
 291  IL_005e:  pop
 292  IL_005f:  ldloc.2
 293  IL_0060:  stloc.s    V_5
 294  IL_0062:  ldloc.s    V_5
 295  IL_0064:  callvirt   ""void D<Base>.Invoke()""
 296  IL_0069:  ldloc.2
 297  IL_006a:  stloc.s    V_5
 298  IL_006c:  ldloc.s    V_5
 299  IL_006e:  dup
 300  IL_006f:  brtrue.s   IL_0073
 301  IL_0071:  pop
 302  IL_0072:  ldloc.1
 303  IL_0073:  callvirt   ""void D<Base>.Invoke()""
 304  IL_0078:  ldnull
 305  IL_0079:  stloc.3
 306  IL_007a:  ldnull
 307  IL_007b:  stloc.s    V_4
 308  IL_007d:  ldloc.0
 309  IL_007e:  pop
 310  IL_007f:  ret
 311}
 312";
 313            var verifier = CompileAndVerify(source, expectedOutput: expectedOutput );
 314            verifier.VerifyIL("Program.Main", expectedIL);
 315        }
 316
 317        [WorkItem(545408, "DevDiv")]
 318        [Fact]
 319        public void TestDelegateContravarianceConversions()
 320        {
 321            var source = @"
 322using System;
 323
 324delegate void D<in T>();
 325
 326class Base { }
 327class Derived : Base { }
 328
 329class Program
 330{
 331    static void Main()
 332    {
 333        bool testFlag = true;
 334
 335        D<Base> baseDelegate = () => Console.Write('B');
 336        D<Derived> derivedDelegate = () => Console.Write('D');
 337
 338        D<Derived> fcn;
 339        
 340        fcn = testFlag ? baseDelegate : derivedDelegate;
 341        fcn();
 342
 343        fcn = testFlag ? derivedDelegate : baseDelegate;
 344        fcn();
 345
 346        fcn = baseDelegate ?? derivedDelegate;
 347        fcn();
 348
 349        fcn = derivedDelegate ?? baseDelegate;
 350        fcn();
 351    }
 352}
 353";
 354            string expectedIL = @"
 355{
 356  // Code size      113 (0x71)
 357  .maxstack  2
 358  .locals init (bool V_0, //testFlag
 359  D<Base> V_1, //baseDelegate
 360  D<Derived> V_2, //derivedDelegate
 361  D<Derived> V_3)
 362  IL_0000:  ldc.i4.1
 363  IL_0001:  stloc.0
 364  IL_0002:  ldsfld     ""D<Base> Program.CS$<>9__CachedAnonymousMethodDelegate1""
 365  IL_0007:  dup
 366  IL_0008:  brtrue.s   IL_001d
 367  IL_000a:  pop
 368  IL_000b:  ldnull
 369  IL_000c:  ldftn      ""void Program.<Main>b__0(object)""
 370  IL_0012:  newobj     ""D<Base>..ctor(object, System.IntPtr)""
 371  IL_0017:  dup
 372  IL_0018:  stsfld     ""D<Base> Program.CS$<>9__CachedAnonymousMethodDelegate1""
 373  IL_001d:  stloc.1
 374  IL_001e:  ldsfld     ""D<Derived> Program.CS$<>9__CachedAnonymousMethodDelegate3""
 375  IL_0023:  dup
 376  IL_0024:  brtrue.s   IL_0039
 377  IL_0026:  pop
 378  IL_0027:  ldnull
 379  IL_0028:  ldftn      ""void Program.<Main>b__2(object)""
 380  IL_002e:  newobj     ""D<Derived>..ctor(object, System.IntPtr)""
 381  IL_0033:  dup
 382  IL_0034:  stsfld     ""D<Derived> Program.CS$<>9__CachedAnonymousMethodDelegate3""
 383  IL_0039:  stloc.2
 384  IL_003a:  ldloc.0
 385  IL_003b:  brtrue.s   IL_0040
 386  IL_003d:  ldloc.2
 387  IL_003e:  br.s       IL_0043
 388  IL_0040:  ldloc.1
 389  IL_0041:  stloc.3
 390  IL_0042:  ldloc.3
 391  IL_0043:  callvirt   ""void D<Derived>.Invoke()""
 392  IL_0048:  ldloc.0
 393  IL_0049:  brtrue.s   IL_0050
 394  IL_004b:  ldloc.1
 395  IL_004c:  stloc.3
 396  IL_004d:  ldloc.3
 397  IL_004e:  br.s       IL_0051
 398  IL_0050:  ldloc.2
 399  IL_0051:  callvirt   ""void D<Derived>.Invoke()""
 400  IL_0056:  ldloc.1
 401  IL_0057:  stloc.3
 402  IL_0058:  ldloc.3
 403  IL_0059:  dup
 404  IL_005a:  brtrue.s   IL_005e
 405  IL_005c:  pop
 406  IL_005d:  ldloc.2
 407  IL_005e:  callvirt   ""void D<Derived>.Invoke()""
 408  IL_0063:  ldloc.2
 409  IL_0064:  dup
 410  IL_0065:  brtrue.s   IL_006b
 411  IL_0067:  pop
 412  IL_0068:  ldloc.1
 413  IL_0069:  stloc.3
 414  IL_006a:  ldloc.3
 415  IL_006b:  callvirt   ""void D<Derived>.Invoke()""
 416  IL_0070:  ret
 417}
 418";
 419
 420            var verifier = CompileAndVerify(source, expectedOutput: @"BDBD");
 421            verifier.VerifyIL("Program.Main", expectedIL);
 422        }
 423
 424        [WorkItem(545408, "DevDiv")]
 425        [Fact]
 426        public void TestInterfaceCovarianceConversions()
 427        {
 428            string source = @"
 429using System;
 430
 431interface I<out T> { }
 432
 433class Base { }
 434class Derived : Base { }
 435
 436class B : I<Base> { }
 437class D : I<Derived> { }
 438
 439class Program
 440{
 441    static void Main()
 442    {
 443        bool testFlag = true;
 444
 445        I<Base> baseInstance = new B();
 446        I<Derived> derivedInstance = new D();
 447
 448        I<Base> i;
 449        
 450        i = testFlag ? baseInstance : derivedInstance;
 451        Console.Write(i.GetType().Name);
 452
 453        i = testFlag ? derivedInstance : baseInstance;
 454        Console.Write(i.GetType().Name);
 455
 456        i = baseInstance ?? derivedInstance;
 457        Console.Write(i.GetType().Name);
 458
 459        i = derivedInstance ?? baseInstance;
 460        Console.Write(i.GetType().Name);
 461    }
 462}
 463";
 464            string expectedIL = @"
 465{
 466  // Code size      109 (0x6d)
 467  .maxstack  2
 468  .locals init (bool V_0, //testFlag
 469  I<Base> V_1, //baseInstance
 470  I<Derived> V_2, //derivedInstance
 471  I<Base> V_3)
 472  IL_0000:  ldc.i4.1
 473  IL_0001:  stloc.0
 474  IL_0002:  newobj     ""B..ctor()""
 475  IL_0007:  stloc.1
 476  IL_0008:  newobj     ""D..ctor()""
 477  IL_000d:  stloc.2
 478  IL_000e:  ldloc.0
 479  IL_000f:  brtrue.s   IL_0016
 480  IL_0011:  ldloc.2
 481  IL_0012:  stloc.3
 482  IL_0013:  ldloc.3
 483  IL_0014:  br.s       IL_0017
 484  IL_0016:  ldloc.1
 485  IL_0017:  callvirt   ""System.Type object.GetType()""
 486  IL_001c:  callvirt   ""string System.Reflection.MemberInfo.Name.get""
 487  IL_0021:  call       ""void System.Console.Write(string)""
 488  IL_0026:  ldloc.0
 489  IL_0027:  brtrue.s   IL_002c
 490  IL_0029:  ldloc.1
 491  IL_002a:  br.s       IL_002f
 492  IL_002c:  ldloc.2
 493  IL_002d:  stloc.3
 494  IL_002e:  ldloc.3
 495  IL_002f:  callvirt   ""System.Type object.GetType()""
 496  IL_0034:  callvirt   ""string System.Reflection.MemberInfo.Name.get""
 497  IL_0039:  call       ""void System.Console.Write(string)""
 498  IL_003e:  ldloc.1
 499  IL_003f:  dup
 500  IL_0040:  brtrue.s   IL_0046
 501  IL_0042:  pop
 502  IL_0043:  ldloc.2
 503  IL_0044:  stloc.3
 504  IL_0045:  ldloc.3
 505  IL_0046:  callvirt   ""System.Type object.GetType()""
 506  IL_004b:  callvirt   ""string System.Reflection.MemberInfo.Name.get""
 507  IL_0050:  call       ""void System.Console.Write(string)""
 508  IL_0055:  ldloc.2
 509  IL_0056:  stloc.3
 510  IL_0057:  ldloc.3
 511  IL_0058:  dup
 512  IL_0059:  brtrue.s   IL_005d
 513  IL_005b:  pop
 514  IL_005c:  ldloc.1
 515  IL_005d:  callvirt   ""System.Type object.GetType()""
 516  IL_0062:  callvirt   ""string System.Reflection.MemberInfo.Name.get""
 517  IL_0067:  call       ""void System.Console.Write(string)""
 518  IL_006c:  ret
 519}
 520";
 521
 522            var verifier = CompileAndVerify(source, expectedOutput: @"BDBD");
 523            verifier.VerifyIL("Program.Main", expectedIL);
 524        }
 525
 526        [WorkItem(545408, "DevDiv")]
 527        [Fact]
 528        public void TestInterfaceContravarianceConversions()
 529        {
 530            string source = @"
 531using System;
 532
 533interface I<in T> { }
 534
 535class Base { }
 536class Derived : Base { }
 537
 538class B : I<Base> { }
 539class D : I<Derived> { }
 540
 541class Program
 542{
 543    static void Main()
 544    {
 545        bool testFlag = true;
 546
 547        I<Base> baseInstance = new B();
 548        I<Derived> derivedInstance = new D();
 549
 550        I<Derived> i;
 551        
 552        i = testFlag ? baseInstance : derivedInstance;
 553        Console.Write(i.GetType().Name);
 554
 555        i = testFlag ? derivedInstance : baseInstance;
 556        Console.Write(i.GetType().Name);
 557
 558        i = baseInstance ?? derivedInstance;
 559        Console.Write(i.GetType().Name);
 560
 561        i = derivedInstance ?? baseInstance;
 562        Console.Write(i.GetType().Name);
 563    }
 564}
 565";
 566            string expectedIL = @"
 567{
 568  // Code size      109 (0x6d)
 569  .maxstack  2
 570  .locals init (bool V_0, //testFlag
 571  I<Base> V_1, //baseInstance
 572  I<Derived> V_2, //derivedInstance
 573  I<Derived> V_3)
 574  IL_0000:  ldc.i4.1
 575  IL_0001:  stloc.0
 576  IL_0002:  newobj     ""B..ctor()""
 577  IL_0007:  stloc.1
 578  IL_0008:  newobj     ""D..ctor()""
 579  IL_000d:  stloc.2
 580  IL_000e:  ldloc.0
 581  IL_000f:  brtrue.s   IL_0014
 582  IL_0011:  ldloc.2
 583  IL_0012:  br.s       IL_0017
 584  IL_0014:  ldloc.1
 585  IL_0015:  stloc.3
 586  IL_0016:  ldloc.3
 587  IL_0017:  callvirt   ""System.Type object.GetType()""
 588  IL_001c:  callvirt   ""string System.Reflection.MemberInfo.Name.get""
 589  IL_0021:  call       ""void System.Console.Write(string)""
 590  IL_0026:  ldloc.0
 591  IL_0027:  brtrue.s   IL_002e
 592  IL_0029:  ldloc.1
 593  IL_002a:  stloc.3
 594  IL_002b:  ldloc.3
 595  IL_002c:  br.s       IL_002f
 596  IL_002e:  ldloc.2
 597  IL_002f:  callvirt   ""System.Type object.GetType()""
 598  IL_0034:  callvirt   ""string System.Reflection.MemberInfo.Name.get""
 599  IL_0039:  call       ""void System.Console.Write(string)""
 600  IL_003e:  ldloc.1
 601  IL_003f:  stloc.3
 602  IL_0040:  ldloc.3
 603  IL_0041:  dup
 604  IL_0042:  brtrue.s   IL_0046
 605  IL_0044:  pop
 606  IL_0045:  ldloc.2
 607  IL_0046:  callvirt   ""System.Type object.GetType()""
 608  IL_004b:  callvirt   ""string System.Reflection.MemberInfo.Name.get""
 609  IL_0050:  call       ""void System.Console.Write(string)""
 610  IL_0055:  ldloc.2
 611  IL_0056:  dup
 612  IL_0057:  brtrue.s   IL_005d
 613  IL_0059:  pop
 614  IL_005a:  ldloc.1
 615  IL_005b:  stloc.3
 616  IL_005c:  ldloc.3
 617  IL_005d:  callvirt   ""System.Type object.GetType()""
 618  IL_0062:  callvirt   ""string System.Reflection.MemberInfo.Name.get""
 619  IL_0067:  call       ""void System.Console.Write(string)""
 620  IL_006c:  ret
 621}
 622";
 623
 624            var verifier = CompileAndVerify(source, expectedOutput: @"BDBD");
 625            verifier.VerifyIL("Program.Main", expectedIL);
 626        }
 627
 628        [Fact]
 629        public void TestBug7196()
 630        {
 631            string source = @"
 632using System;
 633using System.Linq.Expressions;
 634using System.Linq;
 635using System.Collections;
 636using System.Collections.Generic;
 637using System.Security;
 638
 639[assembly: SecurityTransparent()]
 640
 641class Program
 642{
 643    private static bool testFlag = false;
 644
 645    static void Main()
 646    {
 647
 648            IEnumerable<string> v1 = Enumerable.Repeat<string>(""string"", 1);
 649            IEnumerable<object> v2 = Enumerable.Empty<object>();
 650            IEnumerable<object> v3 = testFlag ? v2 : v1;
 651
 652            if (!testFlag){
 653                Console.WriteLine(v3.Count());
 654            }
 655    }
 656}
 657";
 658            string expectedIL = @"
 659{
 660  // Code size       51 (0x33)
 661  .maxstack  2
 662  .locals init (System.Collections.Generic.IEnumerable<string> V_0, //v1
 663  System.Collections.Generic.IEnumerable<object> V_1, //v2
 664  System.Collections.Generic.IEnumerable<object> V_2, //v3
 665  System.Collections.Generic.IEnumerable<object> V_3)
 666  IL_0000:  ldstr      ""string""
 667  IL_0005:  ldc.i4.1
 668  IL_0006:  call       ""System.Collections.Generic.IEnumerable<string> System.Linq.Enumerable.Repeat<string>(string, int)""
 669  IL_000b:  stloc.0
 670  IL_000c:  call       ""System.Collections.Generic.IEnumerable<object> System.Linq.Enumerable.Empty<object>()""
 671  IL_0011:  stloc.1
 672  IL_0012:  ldsfld     ""bool Program.testFlag""
 673  IL_0017:  brtrue.s   IL_001e
 674  IL_0019:  ldloc.0
 675  IL_001a:  stloc.3
 676  IL_001b:  ldloc.3
 677  IL_001c:  br.s       IL_001f
 678  IL_001e:  ldloc.1
 679  IL_001f:  stloc.2
 680  IL_0020:  ldsfld     ""bool Program.testFlag""
 681  IL_0025:  brtrue.s   IL_0032
 682  IL_0027:  ldloc.2
 683  IL_0028:  call       ""int System.Linq.Enumerable.Count<object>(System.Collections.Generic.IEnumerable<object>)""
 684  IL_002d:  call       ""void System.Console.WriteLine(int)""
 685  IL_0032:  ret
 686}
 687";
 688
 689            var verifier = CompileAndVerify(new string[] { source }, additionalRefs: new[] { SystemCoreRef }, expectedOutput:"1");
 690            verifier.VerifyIL("Program.Main", expectedIL);
 691        }
 692
 693        [Fact]
 694        public void TestBug7196a()
 695        {
 696            string source = @"
 697using System;
 698using System.Linq.Expressions;
 699using System.Linq;
 700using System.Collections;
 701using System.Collections.Generic;
 702using System.Security;
 703
 704[assembly: SecurityTransparent()]
 705
 706class Program
 707{
 708    private static bool testFlag = true;
 709
 710    static void Main()
 711    {
 712
 713            IEnumerable<string> v1 = Enumerable.Repeat<string>(""string"", 1);
 714            IEnumerable<object> v2 = Enumerable.Empty<object>();
 715            IEnumerable<object> v3 = v1 ?? v2;
 716
 717            if (testFlag){
 718                Console.WriteLine(v3.Count());
 719            }
 720    }
 721}
 722";
 723            string expectedIL = @"
 724{
 725  // Code size       44 (0x2c)
 726  .maxstack  2
 727  .locals init (System.Collections.Generic.IEnumerable<object> V_0, //v2
 728  System.Collections.Generic.IEnumerable<object> V_1, //v3
 729  System.Collections.Generic.IEnumerable<object> V_2)
 730  IL_0000:  ldstr      ""string""
 731  IL_0005:  ldc.i4.1
 732  IL_0006:  call       ""System.Collections.Generic.IEnumerable<string> System.Linq.Enumerable.Repeat<string>(string, int)""
 733  IL_000b:  call       ""System.Collections.Generic.IEnumerable<object> System.Linq.Enumerable.Empty<object>()""
 734  IL_0010:  stloc.0
 735  IL_0011:  stloc.2
 736  IL_0012:  ldloc.2
 737  IL_0013:  dup
 738  IL_0014:  brtrue.s   IL_0018
 739  IL_0016:  pop
 740  IL_0017:  ldloc.0
 741  IL_0018:  stloc.1
 742  IL_0019:  ldsfld     ""bool Program.testFlag""
 743  IL_001e:  brfalse.s  IL_002b
 744  IL_0020:  ldloc.1
 745  IL_0021:  call       ""int System.Linq.Enumerable.Count<object>(System.Collections.Generic.IEnumerable<object>)""
 746  IL_0026:  call       ""void System.Console.WriteLine(int)""
 747  IL_002b:  ret
 748}
 749";
 750
 751            var verifier = CompileAndVerify(new string[] { source }, additionalRefs: new[] { SystemCoreRef }, expectedOutput: "1");
 752            verifier.VerifyIL("Program.Main", expectedIL);
 753        }
 754
 755        [Fact]
 756        public void TestBug7196b()
 757        {
 758            string source = @"
 759using System;
 760using System.Linq.Expressions;
 761using System.Linq;
 762using System.Collections;
 763using System.Collections.Generic;
 764using System.Security;
 765
 766[assembly: SecurityTransparent()]
 767
 768class Program
 769{
 770    private static bool testFlag = true;
 771
 772    static void Main()
 773    {
 774
 775            string[] v1 = Enumerable.Repeat<string>(""string"", 1).ToArray();
 776            object[] v2 = Enumerable.Empty<object>().ToArray();
 777            object[] v3 = v1 ?? v2;
 778
 779            if (testFlag){
 780                Console.WriteLine(v3.Length);
 781            }
 782    }
 783}
 784";
 785            string expectedIL = @"
 786{
 787  // Code size       51 (0x33)
 788  .maxstack  2
 789  .locals init (object[] V_0, //v2
 790  object[] V_1, //v3
 791  object[] V_2)
 792  IL_0000:  ldstr      ""string""
 793  IL_0005:  ldc.i4.1
 794  IL_0006:  call       ""System.Collections.Generic.IEnumerable<string> System.Linq.Enumerable.Repeat<string>(string, int)""
 795  IL_000b:  call       ""string[] System.Linq.Enumerable.ToArray<string>(System.Collections.Generic.IEnumerable<string>)""
 796  IL_0010:  call       ""System.Collections.Generic.IEnumerable<object> System.Linq.Enumerable.Empty<object>()""
 797  IL_0015:  call       ""object[] System.Linq.Enumerable.ToArray<object>(System.Collections.Generic.IEnumerable<object>)""
 798  IL_001a:  stloc.0
 799  IL_001b:  stloc.2
 800  IL_001c:  ldloc.2
 801  IL_001d:  dup
 802  IL_001e:  brtrue.s   IL_0022
 803  IL_0020:  pop
 804  IL_0021:  ldloc.0
 805  IL_0022:  stloc.1
 806  IL_0023:  ldsfld     ""bool Program.testFlag""
 807  IL_0028:  brfalse.s  IL_0032
 808  IL_002a:  ldloc.1
 809  IL_002b:  ldlen
 810  IL_002c:  conv.i4
 811  IL_002d:  call       ""void System.Console.WriteLine(int)""
 812  IL_0032:  ret
 813}
 814";
 815
 816            var verifier = CompileAndVerify(new string[] { source }, additionalRefs: new[] { SystemCoreRef }, expectedOutput: "1");
 817            verifier.VerifyIL("Program.Main", expectedIL);
 818        }
 819
 820
 821        [Fact]
 822        public void TestBug7196c()
 823        {
 824            string source = @"
 825using System;
 826using System.Linq.Expressions;
 827using System.Linq;
 828using System.Collections;
 829using System.Collections.Generic;
 830using System.Security;
 831
 832[assembly: SecurityTransparent()]
 833
 834class Program
 835{
 836    private static bool testFlag = true;
 837
 838    static void Main()
 839    {
 840
 841            IEnumerable<string>[] v1 = new IEnumerable<string>[] { Enumerable.Repeat<string>(""string"", 1)};
 842            IEnumerable<object>[] v2 = new IEnumerable<object>[] { Enumerable.Empty<object>()};
 843            IEnumerable<object>[] v3 = v1 ?? v2;
 844
 845            if (testFlag){
 846                Console.WriteLine(v3.Length);
 847            }
 848    }
 849}
 850";
 851            string expectedIL = @"
 852{
 853  // Code size       61 (0x3d)
 854  .maxstack  5
 855  .locals init (System.Collections.Generic.IEnumerable<string>[] V_0, //v1
 856  System.Collections.Generic.IEnumerable<object>[] V_1, //v2
 857  System.Collections.Generic.IEnumerable<object>[] V_2, //v3
 858  System.Collections.Generic.IEnumerable<object>[] V_3)
 859  IL_0000:  ldc.i4.1
 860  IL_0001:  newarr     ""System.Collections.Generic.IEnumerable<string>""
 861  IL_0006:  dup
 862  IL_0007:  ldc.i4.0
 863  IL_0008:  ldstr      ""string""
 864  IL_000d:  ldc.i4.1
 865  IL_000e:  call       ""System.Collections.Generic.IEnumerable<string> System.Linq.Enumerable.Repeat<string>(string, int)""
 866  IL_0013:  stelem.ref
 867  IL_0014:  stloc.0
 868  IL_0015:  ldc.i4.1
 869  IL_0016:  newarr     ""System.Collections.Generic.IEnumerable<object>""
 870  IL_001b:  dup
 871  IL_001c:  ldc.i4.0
 872  IL_001d:  call       ""System.Collections.Generic.IEnumerable<object> System.Linq.Enumerable.Empty<object>()""
 873  IL_0022:  stelem.ref
 874  IL_0023:  stloc.1
 875  IL_0024:  ldloc.0
 876  IL_0025:  stloc.3
 877  IL_0026:  ldloc.3
 878  IL_0027:  dup
 879  IL_0028:  brtrue.s   IL_002c
 880  IL_002a:  pop
 881  IL_002b:  ldloc.1
 882  IL_002c:  stloc.2
 883  IL_002d:  ldsfld     ""bool Program.testFlag""
 884  IL_0032:  brfalse.s  IL_003c
 885  IL_0034:  ldloc.2
 886  IL_0035:  ldlen
 887  IL_0036:  conv.i4
 888  IL_0037:  call       ""void System.Console.WriteLine(int)""
 889  IL_003c:  ret
 890}
 891";
 892
 893            var verifier = CompileAndVerify(new string[] { source }, additionalRefs: new[] { SystemCoreRef }, expectedOutput: "1");
 894            verifier.VerifyIL("Program.Main", expectedIL);
 895        }
 896
 897        [Fact]
 898        public void TestBug7196d()
 899        {
 900            string source = @"
 901using System;
 902using System.Linq.Expressions;
 903using System.Linq;
 904using System.Collections;
 905using System.Collections.Generic;
 906using System.Security;
 907
 908[assembly: SecurityTransparent()]
 909
 910class Program
 911{
 912    private static bool testFlag = true;
 913
 914    static void Main()
 915    {
 916
 917            IEnumerable<string>[] v1 = new IEnumerable<string>[] { Enumerable.Repeat<string>(""string"", 1)};
 918            IEnumerable[] v2 = new IEnumerable<object>[] { Enumerable.Empty<object>()};
 919            IEnumerable[] v3 = v1 ?? v2;
 920
 921            if (testFlag){
 922                Console.WriteLine(v3.Length);
 923            }
 924    }
 925}
 926";
 927            string expectedIL = @"
 928{
 929  // Code size       59 (0x3b)
 930  .maxstack  5
 931  .locals init (System.Collections.Generic.IEnumerable<string>[] V_0, //v1
 932  System.Collections.IEnumerable[] V_1, //v2
 933  System.Collections.IEnumerable[] V_2) //v3
 934  IL_0000:  ldc.i4.1
 935  IL_0001:  newarr     ""System.Collections.Generic.IEnumerable<string>""
 936  IL_0006:  dup
 937  IL_0007:  ldc.i4.0
 938  IL_0008:  ldstr      ""string""
 939  IL_000d:  ldc.i4.1
 940  IL_000e:  call       ""System.Collections.Generic.IEnumerable<string> System.Linq.Enumerable.Repeat<string>(string, int)""
 941  IL_0013:  stelem.ref
 942  IL_0014:  stloc.0
 943  IL_0015:  ldc.i4.1
 944  IL_0016:  newarr     ""System.Collections.Generic.IEnumerable<object>""
 945  IL_001b:  dup
 946  IL_001c:  ldc.i4.0
 947  IL_001d:  call       ""System.Collections.Generic.IEnumerable<object> System.Linq.Enumerable.Empty<object>()""
 948  IL_0022:  stelem.ref
 949  IL_0023:  stloc.1
 950  IL_0024:  ldloc.0
 951  IL_0025:  dup
 952  IL_0026:  brtrue.s   IL_002a
 953  IL_0028:  pop
 954  IL_0029:  ldloc.1
 955  IL_002a:  stloc.2
 956  IL_002b:  ldsfld     ""bool Program.testFlag""
 957  IL_0030:  brfalse.s  IL_003a
 958  IL_0032:  ldloc.2
 959  IL_0033:  ldlen
 960  IL_0034:  conv.i4
 961  IL_0035:  call       ""void System.Console.WriteLine(int)""
 962  IL_003a:  ret
 963}
 964";
 965
 966            var verifier = CompileAndVerify(new string[] { source }, additionalRefs: new[] { SystemCoreRef }, expectedOutput: "1");
 967            verifier.VerifyIL("Program.Main", expectedIL);
 968        }
 969
 970        [WorkItem(545408, "DevDiv")]
 971        [Fact]
 972        public void TestVarianceConversions()
 973        {          
 974            string source = @"
 975using System;
 976using System.Linq.Expressions;
 977using System.Linq;
 978using System.Collections;
 979using System.Collections.Generic;
 980using System.Security;
 981
 982[assembly: SecurityTransparent()]
 983
 984namespace TernaryAndVarianceConversion
 985{
 986    delegate void CovariantDelegateWithVoidReturn<out T>();
 987    delegate T CovariantDelegateWithValidReturn<out T>();
 988
 989    delegate void ContravariantDelegateVoidReturn<in T>();
 990    delegate void ContravariantDelegateWithValidInParm<in T>(T inVal);
 991
 992    interface ICovariantInterface<out T>
 993    {
 994        void CovariantInterfaceMathodWithVoidReturn();
 995        T CovariantInterfaceMathodWithValidReturn();
 996        T CovariantInterfacePropertyWithValidGetter { get; }
 997        void Test();
 998    }
 999
1000    interface IContravariantInterface<in T>
1001    {
1002        void ContravariantInterfaceMathodWithVoidReturn();
1003        void ContravariantInterfaceMathodWithValidInParm(T inVal);
1004        T ContravariantInterfacePropertyWithValidSetter { set; }
1005        void Test();
1006    }
1007
1008    class CovariantInterfaceImpl<T> : ICovariantInterface<T>
1009    {
1010        public void CovariantInterfaceMathodWithVoidReturn() { }
1011        public T CovariantInterfaceMathodWithValidReturn()
1012        {
1013            return default(T);
1014        }
1015        public T CovariantInterfacePropertyWithValidGetter
1016        {
1017            get { return default(T); }
1018        }
1019        public void Test()
1020        {
1021            Console.WriteLine(""{0}"", typeof(T));
1022        }
1023    }
1024
1025    class ContravariantInterfaceImpl<T> : IContravariantInterface<T>
1026    {
1027        public void ContravariantInterfaceMathodWithVoidReturn() { }
1028        public void ContravariantInterfaceMathodWithValidInParm(T inVal) { }
1029        public T ContravariantInterfacePropertyWithValidSetter
1030        {
1031            set { }
1032        }
1033        public void Test()
1034        {
1035            Console.WriteLine(""{0}"", typeof(T));
1036        }
1037    }
1038
1039    class Animal { }
1040    class Mammal : Animal { }
1041
1042    class Program
1043    {
1044        static void Test(bool testFlag)
1045        {
1046            Console.WriteLine(""Testing with ternary test flag == {0}"", testFlag);
1047
1048            // Repro case for bug 7196
1049            IEnumerable<object> EnumerableOfObject =
1050                                    (testFlag ?
1051                                     Enumerable.Repeat<string>(""string"", 1) :
1052                                     Enumerable.Empty<object>());
1053            Console.WriteLine(""{0}"", EnumerableOfObject.Count());
1054
1055
1056            // Covariant implicit conversion for delegates
1057            CovariantDelegateWithVoidReturn<Animal> covariantDelegateWithVoidReturnOfAnimal = () => { Console.WriteLine(""{0}"", typeof(Animal)); };
1058            CovariantDelegateWithVoidReturn<Mammal> covariantDelegateWithVoidReturnOfMammal = () => { Console.WriteLine(""{0}"", typeof(Mammal)); };
1059            CovariantDelegateWithVoidReturn<Animal> covariantDelegateWithVoidReturnOfAnimalTest;
1060            covariantDelegateWithVoidReturnOfAnimalTest = testFlag ? covariantDelegateWithVoidReturnOfMammal : covariantDelegateWithVoidReturnOfAnimal;
1061            covariantDelegateWithVoidReturnOfAnimalTest();
1062            covariantDelegateWithVoidReturnOfAnimalTest = testFlag ? covariantDelegateWithVoidReturnOfAnimal : covariantDelegateWithVoidReturnOfMammal;
1063            covariantDelegateWithVoidReturnOfAnimalTest();
1064
1065            CovariantDelegateWithValidReturn<Animal> covariantDelegateWithValidReturnOfAnimal = () => { Console.WriteLine(""{0}"", typeof(Animal)); return default(Animal); };
1066            CovariantDelegateWithValidReturn<Mammal> covariantDelegateWithValidReturnOfMammal = () => { Console.WriteLine(""{0}"", typeof(Mammal)); return default(Mammal); };
1067            CovariantDelegateWithValidReturn<Animal> covariantDelegateWithValidReturnOfAnimalTest;
1068            covariantDelegateWithValidReturnOfAnimalTest = testFlag ? covariantDelegateWithValidReturnOfMammal : covariantDelegateWithValidReturnOfAnimal;
1069            covariantDelegateWithValidReturnOfAnimalTest();
1070            covariantDelegateWithValidReturnOfAnimalTest = testFlag ? covariantDelegateWithValidReturnOfAnimal : covariantDelegateWithValidReturnOfMammal;
1071            covariantDelegateWithValidReturnOfAnimalTest();
1072
1073            // Contravariant implicit conversion for delegates
1074            ContravariantDelegateVoidReturn<Animal> contravariantDelegateVoidReturnOfAnimal = () => { Console.WriteLine(""{0}"", typeof(Animal)); };
1075            ContravariantDelegateVoidReturn<Mammal> contravariantDelegateVoidReturnOfMammal = () => { Console.WriteLine(""{0}"", typeof(Mammal)); };
1076            ContravariantDelegateVoidReturn<Mammal> contravariantDelegateVoidReturnOfMammalTest;
1077            contravariantDelegateVoidReturnOfMammalTest = testFlag ? contravariantDelegateVoidReturnOfMammal : contravariantDelegateVoidReturnOfAnimal;
1078            contravariantDelegateVoidReturnOfMammalTest();
1079            contravariantDelegateVoidReturnOfMammalTest = testFlag ? contravariantDelegateVoidReturnOfAnimal : contravariantDelegateVoidReturnOfMammal;
1080            contravariantDelegateVoidReturnOfMammalTest();
1081
1082            ContravariantDelegateWithValidInParm<Animal> contravariantDelegateWithValidInParmOfAnimal = (Animal) => { Console.WriteLine(""{0}"", typeof(Animal)); };
1083            ContravariantDelegateWithValidInParm<Mammal> contravariantDelegateWithValidInParmOfMammal = (Mammal) => { Console.WriteLine(""{0}"", typeof(Mammal)); };
1084            ContravariantDelegateWithValidInParm<Mammal> contravariantDelegateWithValidInParmOfMammalTest;
1085            contravariantDelegateWithValidInParmOfMammalTest = testFlag ? contravariantDelegateWithValidInParmOfMammal : contravariantDelegateWithValidInParmOfAnimal;
1086            contravariantDelegateWithValidInParmOfMammalTest(default(Mammal));
1087            contravariantDelegateWithValidInParmOfMammalTest = testFlag ? contravariantDelegateWithValidInParmOfAnimal : contravariantDelegateWithValidInParmOfMammal;
1088            contravariantDelegateWithValidInParmOfMammalTest(default(Mammal));
1089
1090            // Covariant implicit conversion for interfaces
1091            ICovariantInterface<Animal> covariantInterfaceOfAnimal = new CovariantInterfaceImpl<Animal>();
1092            ICovariantInterface<Mammal> covariantInterfaceOfMammal = new CovariantInterfaceImpl<Mammal>();
1093            ICovariantInterface<Animal> covariantInterfaceOfAnimalTest;
1094            covariantInterfaceOfAnimalTest = testFlag ? covariantInterfaceOfMammal : covariantInterfaceOfAnimal;
1095            covariantInterfaceOfAnimalTest.Test();
1096            covariantInterfaceOfAnimalTest = testFlag ? covariantInterfaceOfAnimal : covariantInterfaceOfMammal;
1097            covariantInterfaceOfAnimalTest.Test();
1098
1099            // Contravariant implicit conversion for interfaces
1100            IContravariantInterface<Animal> contravariantInterfaceOfAnimal = new ContravariantInterfaceImpl<Animal>();
1101            IContravariantInterface<Mammal> contravariantInterfaceOfMammal = new ContravariantInterfaceImpl<Mammal>();
1102            IContravariantInterface<Mammal> contravariantInterfaceOfMammalTest;
1103            contravariantInterfaceOfMammalTest = testFlag ? contravariantInterfaceOfMammal : contravariantInterfaceOfAnimal;
1104            contravariantInterfaceOfMammalTest.Test();
1105            contravariantInterfaceOfMammalTest = testFlag ? contravariantInterfaceOfAnimal : contravariantInterfaceOfMammal;
1106            contravariantInterfaceOfMammalTest.Test();
1107
1108            // With explicit casting
1109            covariantDelegateWithVoidReturnOfAnimalTest = testFlag ? (CovariantDelegateWithVoidReturn<Animal>)covariantDelegateWithVoidReturnOfMammal : covariantDelegateWithVoidReturnOfAnimal;
1110            covariantDelegateWithVoidReturnOfAnimalTest();
1111            covariantDelegateWithVoidReturnOfAnimalTest = testFlag ? covariantDelegateWithVoidReturnOfAnimal : (CovariantDelegateWithVoidReturn<Animal>)covariantDelegateWithVoidReturnOfMammal;
1112            covariantDelegateWithVoidReturnOfAnimalTest();
1113
1114            // With parens
1115            covariantDelegateWithVoidReturnOfAnimalTest = testFlag ? (covariantDelegateWithVoidReturnOfMammal) : covariantDelegateWithVoidReturnOfAnimal;
1116            covariantDelegateWithVoidReturnOfAnimalTest();
1117            covariantDelegateWithVoidReturnOfAnimalTest = testFlag ? covariantDelegateWithVoidReturnOfAnimal : (covariantDelegateWithVoidReturnOfMammal);
1118            covariantDelegateWithVoidReturnOfAnimalTest();
1119            covariantDelegateWithVoidReturnOfAnimalTest = testFlag ? ((CovariantDelegateWithVoidReturn<Animal>)covariantDelegateWithVoidReturnOfMammal) : covariantDelegateWithVoidReturnOfAnimal;
1120            covariantDelegateWithVoidReturnOfAnimalTest();
1121            covariantDelegateWithVoidReturnOfAnimalTest = testFlag ? covariantDelegateWithVoidReturnOfAnimal : ((CovariantDelegateWithVoidReturn<Animal>)covariantDelegateWithVoidReturnOfMammal);
1122            covariantDelegateWithVoidReturnOfAnimalTest();
1123
1124            // Bug 291602
1125            int[] intarr = { 1, 2, 3 };
1126            IList<int> intlist = new List<int>(intarr);
1127            IList<int> intternary = testFlag ? intarr : intlist;
1128            Console.WriteLine(intternary);
1129        }
1130        static void Main(string[] args)
1131        {
1132            Test(true);
1133            Test(false);
1134        }
1135    }
1136}
1137";
1138            var compilation = CreateCompilationWithMscorlibAndSystemCore(source, compOptions: TestOptions.Exe);
1139            CompileAndVerify(compilation, expectedOutput: @"Testing with ternary test flag == True
11401
1141TernaryAndVarianceConversion.Mammal
1142TernaryAndVarianceConversion.Animal
1143TernaryAndVarianceConversion.Mammal
1144TernaryAndVarianceConversion.Animal
1145TernaryAndVarianceConversion.Mammal
1146TernaryAndVarianceConversion.Animal
1147TernaryAndVarianceConversion.Mammal
1148TernaryAndVarianceConversion.Animal
1149TernaryAndVarianceConversion.Mammal
1150TernaryAndVarianceConversion.Animal
1151TernaryAndVarianceConversion.Mammal
1152TernaryAndVarianceConversion.Animal
1153TernaryAndVarianceConversion.Mammal
1154TernaryAndVarianceConversion.Animal
1155TernaryAndVarianceConversion.Mammal
1156TernaryAndVarianceConversion.Animal
1157TernaryAndVarianceConversion.Mammal
1158TernaryAndVarianceConversion.Animal
1159System.Int32[]
1160Testing with ternary test flag == False
11610
1162TernaryAndVarianceConversion.Animal
1163TernaryAndVarianceConversion.Mammal
1164TernaryAndVarianceConversion.Animal
1165TernaryAndVarianceConversion.Mammal
1166TernaryAndVarianceConversion.Animal
1167TernaryAndVarianceConversion.Mammal
1168TernaryAndVarianceConversion.Animal
1169TernaryAndVarianceConversion.Mammal
1170TernaryAndVarianceConversion.Animal
1171TernaryAndVarianceConversion.Mammal
1172TernaryAndVarianceConversion.Animal
1173TernaryAndVarianceConversion.Mammal
1174TernaryAndVarianceConversion.Animal
1175TernaryAndVarianceConversion.Mammal
1176TernaryAndVarianceConversion.Animal
1177TernaryAndVarianceConversion.Mammal
1178TernaryAndVarianceConversion.Animal
1179TernaryAndVarianceConversion.Mammal
1180System.Collections.Generic.List`1[System.Int32]
1181");
1182        }
1183
1184        [WorkItem(528424, "DevDiv")]
1185        [Fact()]
1186        public void TestErrorOperand()
1187        {
1188            var source =
1189@"class C
1190{
1191    static object M(bool b, C c, D d)
1192    {
1193        return b ? c : d;
1194    }
1195}";
1196            CreateCompilationWithMscorlib(source).VerifyDiagnostics(
1197                // (3,34): error CS0246: The type or namespace name 'D' could not be found (are you missing a using directive or an assembly reference?)
1198                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "D").WithArguments("D"));
1199        }
1200
1201        private static void TestConditional(string conditionalExpression, string expectedType, params DiagnosticDescription[] expectedDiagnostics)
1202        {
1203            string sourceTemplate = @"
1204class C
1205{{
1206    void Test<T, U>()
1207    {{
1208        System.Console.WriteLine({0});
1209    }}
1210
1211    int GetInt() {{ return 1; }}
1212    void GetVoid() {{ return ; }}
1213    bool GetBool() {{ return true; }}
1214    short GetShort() {{ return 1; }}
1215    char GetChar() {{ return 'a'; }}
1216    double GetDouble() {{ return 1.5; }}
1217    string GetString() {{ return ""hello""; }}
1218    object GetObject() {{ return new object(); }}
1219    C GetUserNonGeneric() {{ return new C(); }}
1220    D<T> GetUserGeneric<T>() {{ return new D<T>(); }}
1221    T GetTypeParameter<T>() {{ return default(T); }}
1222    I<T, U> GetVariantInterface<T, U>() {{ return null; }}
1223}}
1224
1225class D<T> {{ }}
1226public enum color {{ Red, Blue, Green }};
1227interface I<in T, out U> {{ }}";
1228
1229            var source = string.Format(sourceTemplate, conditionalExpression);
1230            var tree = Parse(source);
1231
1232            var comp = CreateCompilationWithMscorlib(tree);
1233            comp.VerifyDiagnostics(expectedDiagnostics);
1234
1235            var compUnit = tree.GetCompilationUnitRoot();
1236            var classC = (TypeDeclarationSyntax)compUnit.Members.First();
1237            var methodTest = (MethodDeclarationSyntax)classC.Members.First();
1238            var stmt = (ExpressionStatementSyntax)methodTest.Body.Statements.Single();
1239            var invocationExpr = (InvocationExpressionSyntax)stmt.Expression;
1240            var conditionalExpr = (ConditionalExpressionSyntax)invocationExpr.ArgumentList.Arguments.Single().Expression;
1241
1242            var model = comp.GetSemanticModel(tree);
1243
1244            if (expectedType != null)
1245            {
1246                Assert.Equal(expectedType, model.GetTypeInfo(conditionalExpr).Type.ToTestDisplayString());
1247
1248                if (!expectedDiagnostics.Any())
1249                {
1250                    Assert.Equal(SpecialType.System_Boolean, model.GetTypeInfo(conditionalExpr.Condition).Type.SpecialType);
1251                    Assert.Equal(expectedType, model.GetTypeInfo(conditionalExpr.WhenTrue).ConvertedType.ToTestDisplayString()); //in parent to catch conversion
1252                    Assert.Equal(expectedType, model.GetTypeInfo(conditionalExpr.WhenFalse).ConvertedType.ToTestDisplayString()); //in parent to catch conversion
1253                }
1254            }
1255        }
1256    }
1257}