public void UnmanagedTypeModreqIsCopiedToOverrides_Interface_Explicit_Compilation() { var reference = CompileAndVerify(@" public interface Parent { string M<T>() where T : unmanaged; } public class Child : Parent { string Parent.M<T>() => ""Child""; }", symbolValidator: module => { var parentTypeParameter = module.ContainingAssembly.GetTypeByMetadataName("Parent").GetMethod("M").TypeParameters.Single(); Assert.True(parentTypeParameter.HasValueTypeConstraint); Assert.True(parentTypeParameter.HasUnmanagedTypeConstraint); AttributeTests_IsUnmanaged.AssertReferencedIsUnmanagedAttribute(Accessibility.Internal, parentTypeParameter, module.ContainingAssembly.Name); var childTypeParameter = module.ContainingAssembly.GetTypeByMetadataName("Child").GetMethod("Parent.M").TypeParameters.Single(); Assert.True(childTypeParameter.HasValueTypeConstraint); Assert.True(childTypeParameter.HasUnmanagedTypeConstraint); AttributeTests_IsUnmanaged.AssertReferencedIsUnmanagedAttribute(Accessibility.Internal, childTypeParameter, module.ContainingAssembly.Name); }); CompileAndVerify(@" class Program { public static void Main() { Parent obj = new Child(); System.Console.WriteLine(obj.M<int>()); } }", references: new[] { reference.Compilation.EmitToImageReference() }, expectedOutput: "Child"); }
public void UnmanagedTypeModreqIsCopiedToLambda_Reference() { var reference = CompileAndVerify(@" public delegate T D<T>() where T : unmanaged; public class TestRef { public static void Print<T>(D<T> lambda) where T : unmanaged { System.Console.WriteLine(lambda()); } }", symbolValidator: module => { var typeParameter = module.ContainingAssembly.GetTypeByMetadataName("D`1").TypeParameters.Single(); Assert.True(typeParameter.HasValueTypeConstraint); Assert.True(typeParameter.HasUnmanagedTypeConstraint); Assert.False(typeParameter.HasConstructorConstraint); // .ctor is an artifact of emit, we will ignore it on importing. AttributeTests_IsUnmanaged.AssertReferencedIsUnmanagedAttribute(Accessibility.Internal, typeParameter, module.ContainingAssembly.Name); }); CompileAndVerify(@" public class Program { static void Test<T>(T arg) where T : unmanaged { TestRef.Print(() => arg); } public static void Main() { Test(5); } }", expectedOutput: "5", references: new[] { reference.Compilation.EmitToImageReference() }, options: TestOptions.ReleaseExe.WithMetadataImportOptions(MetadataImportOptions.All), symbolValidator: module => { var typeParameter = module.ContainingAssembly.GetTypeByMetadataName("Program").GetTypeMember("<>c__DisplayClass0_0").TypeParameters.Single(); Assert.True(typeParameter.HasValueTypeConstraint); Assert.True(typeParameter.HasUnmanagedTypeConstraint); Assert.False(typeParameter.HasConstructorConstraint); // .ctor is an artifact of emit, we will ignore it on importing. AttributeTests_IsUnmanaged.AssertReferencedIsUnmanagedAttribute(Accessibility.Internal, typeParameter, module.ContainingAssembly.Name); }); }
public void UnmanagedTypeModreqIsCopiedToOverrides_Virtual_Reference() { var parent = CompileAndVerify(@" public class Parent { public virtual string M<T>() where T : unmanaged => ""Parent""; }", symbolValidator: module => { var typeParameter = module.ContainingAssembly.GetTypeByMetadataName("Parent").GetMethod("M").TypeParameters.Single(); Assert.True(typeParameter.HasValueTypeConstraint); Assert.True(typeParameter.HasUnmanagedTypeConstraint); AttributeTests_IsUnmanaged.AssertReferencedIsUnmanagedAttribute(Accessibility.Internal, typeParameter, module.ContainingAssembly.Name); }); var child = CompileAndVerify(@" public class Child : Parent { public override string M<T>() => ""Child""; }", references: new[] { parent.Compilation.EmitToImageReference() }, symbolValidator: module => { var typeParameter = module.ContainingAssembly.GetTypeByMetadataName("Child").GetMethod("M").TypeParameters.Single(); Assert.True(typeParameter.HasValueTypeConstraint); Assert.True(typeParameter.HasUnmanagedTypeConstraint); AttributeTests_IsUnmanaged.AssertReferencedIsUnmanagedAttribute(Accessibility.Internal, typeParameter, module.ContainingAssembly.Name); }); CompileAndVerify(@" class Program { public static void Main() { System.Console.WriteLine(new Parent().M<int>()); System.Console.WriteLine(new Child().M<int>()); } }", references: new[] { parent.Compilation.EmitToImageReference(), child.Compilation.EmitToImageReference() }, expectedOutput: @" Parent Child"); }
public void UnmanagedTypeModreqIsCopiedToLambda_Compilation() { CompileAndVerify(@" public delegate T D<T>() where T : unmanaged; public class TestRef { public static void Print<T>(D<T> lambda) where T : unmanaged { System.Console.WriteLine(lambda()); } } public class Program { static void Test<T>(T arg) where T : unmanaged { TestRef.Print(() => arg); } public static void Main() { Test(5); } }", expectedOutput: "5", options: TestOptions.ReleaseExe.WithMetadataImportOptions(MetadataImportOptions.All), symbolValidator: module => { var delegateTypeParameter = module.ContainingAssembly.GetTypeByMetadataName("D`1").TypeParameters.Single(); Assert.True(delegateTypeParameter.HasValueTypeConstraint); Assert.True(delegateTypeParameter.HasUnmanagedTypeConstraint); AttributeTests_IsUnmanaged.AssertReferencedIsUnmanagedAttribute(Accessibility.Internal, delegateTypeParameter, module.ContainingAssembly.Name); var lambdaTypeParameter = module.ContainingAssembly.GetTypeByMetadataName("Program").GetTypeMember("<>c__DisplayClass0_0").TypeParameters.Single(); Assert.True(lambdaTypeParameter.HasValueTypeConstraint); Assert.True(lambdaTypeParameter.HasUnmanagedTypeConstraint); AttributeTests_IsUnmanaged.AssertReferencedIsUnmanagedAttribute(Accessibility.Internal, lambdaTypeParameter, module.ContainingAssembly.Name); }); }