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