|
| 1 | +using System; |
| 2 | +using System.Collections.Generic; |
| 3 | + |
| 4 | +public interface CovariantInterface<out T> { } |
| 5 | + |
| 6 | +public interface ContravariantInterface<in T> { } |
| 7 | + |
| 8 | +public interface InvariantInterface<T> { } |
| 9 | + |
| 10 | +public interface MixedInterface<out T1, in T2> { } |
| 11 | + |
| 12 | +public class Base { } |
| 13 | + |
| 14 | +public class Derived : Base { } |
| 15 | + |
| 16 | +public class C |
| 17 | +{ |
| 18 | + public void M() |
| 19 | + { |
| 20 | + string[] stringArray = []; |
| 21 | + string[][] stringArrayArray = []; |
| 22 | + string[,] stringArray2D = new string[0, 0]; |
| 23 | + |
| 24 | + Span<string> stringSpan = stringArray; // string[] -> Span<string>; |
| 25 | + |
| 26 | + // Assignments are included to illustrate that it compiles. |
| 27 | + // Only the use of the types matter in terms of test output. |
| 28 | + // Covariant conversions to ReadOnlySpan |
| 29 | + ReadOnlySpan<CovariantInterface<Base>> covariantInterfaceBaseReadOnlySpan; |
| 30 | + ReadOnlySpan<CovariantInterface<Derived>> covariantInterfaceDerivedReadOnlySpan = default; |
| 31 | + Span<CovariantInterface<Derived>> covariantInterfaceDerivedSpan = default; |
| 32 | + CovariantInterface<Derived>[] covariantInterfaceDerivedArray = []; |
| 33 | + covariantInterfaceBaseReadOnlySpan = covariantInterfaceDerivedReadOnlySpan; // ReadOnlySpan<CovariantInterface<Derived>> -> ReadOnlySpan<CovariantInterface<Base>> |
| 34 | + covariantInterfaceBaseReadOnlySpan = covariantInterfaceDerivedSpan; // Span<CovariantInterface<Derived>> -> ReadOnlySpan<CovariantInterface<Base>> |
| 35 | + covariantInterfaceBaseReadOnlySpan = covariantInterfaceDerivedArray; // CovariantInterface<Derived>[] -> ReadOnlySpan<CovariantInterface<Base>> |
| 36 | + |
| 37 | + // Identify conversions to ReadOnlySpan |
| 38 | + ReadOnlySpan<string> stringReadOnlySpan; |
| 39 | + stringReadOnlySpan = stringSpan; // Span<string> -> ReadOnlySpan<string>; |
| 40 | + stringReadOnlySpan = stringArray; // string[] -> ReadOnlySpan<string>; |
| 41 | + |
| 42 | + // Contravariant conversions to ReadOnlySpan |
| 43 | + ReadOnlySpan<ContravariantInterface<Derived>> contravariantInterfaceDerivedReadOnlySpan; |
| 44 | + ReadOnlySpan<ContravariantInterface<Base>> contravariantInterfaceBaseReadOnlySpan = default; |
| 45 | + Span<ContravariantInterface<Base>> contravariantInterfaceBaseSpan = default; |
| 46 | + ContravariantInterface<Base>[] contravariantInterfaceBaseArray = []; |
| 47 | + contravariantInterfaceDerivedReadOnlySpan = contravariantInterfaceBaseReadOnlySpan; // ReadOnlySpan<ContravariantInterface<Base>> -> ReadOnlySpan<ContravariantInterface<Derived>> |
| 48 | + contravariantInterfaceDerivedReadOnlySpan = contravariantInterfaceBaseSpan; // Span<ContravariantInterface<Base>> -> ReadOnlySpan<ContravariantInterface<Derived>> |
| 49 | + contravariantInterfaceDerivedReadOnlySpan = contravariantInterfaceBaseArray; // ContravariantInterface<Base>[] -> ReadOnlySpan<ContravariantInterface<Derived>> |
| 50 | + |
| 51 | + // Mixed variance conversions to ReadOnlySpan |
| 52 | + ReadOnlySpan<MixedInterface<Base, Derived>> mixedInterfaceBaseReadOnlySpan; |
| 53 | + ReadOnlySpan<MixedInterface<Derived, Base>> mixedInterfaceDerivedReadOnlySpan = default; |
| 54 | + Span<MixedInterface<Derived, Base>> mixedInterfaceDerivedSpan = default; |
| 55 | + MixedInterface<Derived, Base>[] mixedInterfaceDerivedArray = []; |
| 56 | + mixedInterfaceBaseReadOnlySpan = mixedInterfaceDerivedReadOnlySpan; // ReadOnlySpan<MixedInterface<Derived, Base>> -> ReadOnlySpan<MixedInterface<Base, Derived>> |
| 57 | + mixedInterfaceBaseReadOnlySpan = mixedInterfaceDerivedSpan; // Span<MixedInterface<Derived, Base>> -> ReadOnlySpan<MixedInterface<Base, Derived>> |
| 58 | + mixedInterfaceBaseReadOnlySpan = mixedInterfaceDerivedArray; // MixedInterface<Derived, Base>[] -> ReadOnlySpan<MixedInterface<Base, Derived>> |
| 59 | + |
| 60 | + // Convert string to ReadOnlySpan<char> |
| 61 | + string s = ""; |
| 62 | + ReadOnlySpan<char> charReadOnlySpan = s; // string -> ReadOnlySpan<char> |
| 63 | + |
| 64 | + // Various ref type conversions |
| 65 | + Derived[] derivedArray = []; |
| 66 | + ReadOnlySpan<Base> baseReadOnlySpan; |
| 67 | + baseReadOnlySpan = derivedArray; // Derived[] -> ReadOnlySpan<Base> |
| 68 | + |
| 69 | + ReadOnlySpan<object> objectReadOnlySpan; |
| 70 | + objectReadOnlySpan = stringArray; // string[] -> ReadOnlySpan<object> |
| 71 | + |
| 72 | + byte[][] byteByteArray = []; |
| 73 | + objectReadOnlySpan = byteByteArray; // byte[][] -> ReadOnlySpan<object> |
| 74 | + |
| 75 | + // No conversion possible except for identity. |
| 76 | + ReadOnlySpan<InvariantInterface<Base>> invariantInterfaceBaseReadOnlySpan; |
| 77 | + ReadOnlySpan<InvariantInterface<Derived>> invariantInterfaceDerivedReadOnlySpan; |
| 78 | + Span<InvariantInterface<Derived>> invariantInterfaceDerivedSpan; |
| 79 | + InvariantInterface<Derived>[] invariantInterfaceDerivedArray; |
| 80 | + } |
| 81 | +} |
0 commit comments