|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable disable
using System;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.CSharp.UnitTests.Emit;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.CodeGen
{
public class CodeGenInterfaceImplementationTests : CSharpTestBase
{
[Fact]
public void TestInterfaceImplementationSimple()
{
// Tests:
// Implement interface that has several base interfaces (several levels of inheritance)
// Implement some members implicitly + some explicitly + some implicitly in base class
// Change parameter names of implemented member
var source = @"
using System;
using System.Collections.Generic;
interface I1
{
int Property { get; set; }
}
interface I2 : I1
{
void Method<T>(int a, ref T[] b, out List<T> c);
}
interface I3 : I2
{
void Method(int a = 3, params System.Exception[] b);
}
class Base
{
public void Method(int b = 4, params System.Exception[] c)
{
System.Console.WriteLine(""Base.Method({0})"", b);
}
public int Property
{
get
{
System.Console.WriteLine(""Derived.Property.get()"");
return 1;
}
set
{
System.Console.WriteLine(""Derived.Property.set({0})"", value);
}
}
}
class Derived : Base, I3
{
public void Method<U>(int i, ref U[] j, out List<U> k)
{
k = null;
System.Console.WriteLine(""Derived.Method<U>({0}, {1})"", i, j[0]);
}
}
class Derived2 : Derived, I1
{
int I1.Property
{
get
{
System.Console.WriteLine(""Derived2.Property.get()"");
return 1;
}
set
{
System.Console.WriteLine(""Derived2.Property.set({0})"", value);
}
}
}
class Class : I3
{
void I3.Method(int b = 4, params System.Exception[] c)
{
System.Console.WriteLine(""Class.Method({0})"", b);
}
void I2.Method<U>(int i, ref U[] j, out List<U> k)
{
k = null;
System.Console.WriteLine(""Class.Method<U>({0}, {1})"", i, j[0]);
}
int I1.Property
{
get
{
System.Console.WriteLine(""Class.Property.get()"");
return 1;
}
set
{
System.Console.WriteLine(""Class.Property.set({0})"", value);
}
}
}
class Test
{
public static void Main()
{
I3 i3 = new Derived2();
string[] s1 = new string[] {""a""};
string[] s2 = new string[] {""b""};
List<string> s3 = null;
i3.Method<string>(1, ref s1, out s3);
i3.Method(2, new ArgumentException());
int x = i3.Property;
i3.Property = x;
i3 = new Derived();
i3.Method<string>(3, ref s2, out s3);
i3.Method(4, new ArgumentException());
x = i3.Property;
i3.Property = x;
i3 = new Class();
i3.Method<string>(5, ref s2, out s3);
i3.Method(6, new ArgumentException());
x = i3.Property;
i3.Property = x;
}
}";
var comp = CompileAndVerify(source,
expectedOutput: @"
Derived.Method<U>(1, a)
Base.Method(2)
Derived2.Property.get()
Derived2.Property.set(1)
Derived.Method<U>(3, b)
Base.Method(4)
Derived.Property.get()
Derived.Property.set(1)
Class.Method<U>(5, b)
Class.Method(6)
Class.Property.get()
Class.Property.set(1)",
expectedSignatures: new[]
{
Signature("Base", "Method", ".method public hidebysig newslot virtual final instance System.Void Method([opt] System.Int32 b = 4, [System.ParamArrayAttribute()] System.Exception[] c) cil managed"),
Signature("Base", "get_Property", ".method public hidebysig newslot specialname virtual final instance System.Int32 get_Property() cil managed"),
Signature("Base", "set_Property", ".method public hidebysig newslot specialname virtual final instance System.Void set_Property(System.Int32 value) cil managed"),
Signature("Derived", "Method", ".method public hidebysig newslot virtual final instance System.Void Method<U>(System.Int32 i, U[]& j, [out] System.Collections.Generic.List`1[U]& k) cil managed"),
Signature("Derived2", "I1.get_Property", ".method private hidebysig newslot specialname virtual final instance System.Int32 I1.get_Property() cil managed"),
Signature("Derived2", "I1.set_Property", ".method private hidebysig newslot specialname virtual final instance System.Void I1.set_Property(System.Int32 value) cil managed"),
Signature("Class", "I1.get_Property", ".method private hidebysig newslot specialname virtual final instance System.Int32 I1.get_Property() cil managed"),
Signature("Class", "I1.set_Property", ".method private hidebysig newslot specialname virtual final instance System.Void I1.set_Property(System.Int32 value) cil managed"),
Signature("Class", "I2.Method", ".method private hidebysig newslot virtual final instance System.Void I2.Method<U>(System.Int32 i, U[]& j, [out] System.Collections.Generic.List`1[U]& k) cil managed"),
Signature("Class", "I3.Method", ".method private hidebysig newslot virtual final instance System.Void I3.Method([opt] System.Int32 b = 4, [System.ParamArrayAttribute()] System.Exception[] c) cil managed")
});
}
[WorkItem(9229, "DevDiv_Projects/Roslyn")]
[Fact]
public void TestImplementingWithAliasedNames()
{
// Tests:
// Use aliased name for type of parameter / return type in implemented member
var source = @"
using System;
using TypeA = Type<int>;
using TypeB = System.Int32;
using TypeC = NS.Derived;
using NSAlias2 = NS;
using NSAlias = NS;
class Type<T>
{
}
interface Interface
{
TypeB Method(System.Exception a, TypeB b, params NS.Derived[] c);
void Method2(TypeC c1, NSAlias2.Derived c2, NS.Derived[] c3);
void Method3(int[] b1, TypeA b2, params int[] b3);
}
namespace NS
{
using TypeA = System.Exception;
using Type = Interface;
using TypeD = Type<int>;
abstract class Base
{
public void Method2(Derived c1, NS.Derived c2, params NSAlias.Derived[] C3)
{
Console.WriteLine(""Base.Method2( , , [{0}])"", C3.Length);
}
}
class Derived : Base, Interface
{
public TypeB Method(TypeA A, int B, TypeC[] C)
{
Console.WriteLine(""Derived.Method( , {0}, [{1}])"", B, C.Length);
return 0;
}
public void Method3(int[] B1, TypeD B2, params int[] b2)
{
Console.WriteLine(""Derived.Method3([{0}], , [{1}])"", B1.Length, b2.Length);
}
}
class Class1 : Type
{
TypeB Type.Method(TypeA A, int B, TypeC[] C)
{
Console.WriteLine(""Class1.Method( , {0}, [{1}])"", B, C.Length);
return 0;
}
void Interface.Method2(Derived c1, NS.Derived c2, NSAlias.Derived[] C3)
{
Console.WriteLine(""Class1.Method2( , , [{0}])"", C3.Length);
}
void Type.Method3(int[] B1, Type<TypeB> B2, params int[] B3)
{
Console.WriteLine(""Class1.Method3([{0}], , [{1}])"", B1.Length, B3.Length);
}
}
}
class Test
{
public static void Main()
{
TypeC d = new TypeC();
TypeA a = new TypeA();
Interface b = d;
d.Method(new System.Exception(), 1, new TypeC[]{d});
b.Method(new System.Exception(), 2, d, d);
b.Method2(d, d, new TypeC[]{d, d, d});
d.Method3(new int[4]{1, 2, 3, 4}, a, new int[5] {6, 7, 8, 9, 10});
b.Method3(new int[6]{1, 2, 3, 4, 5, 6}, a, 8, 9, 10, 11, 12, 13, 14);
b = new NS.Class1();
b.Method(new System.Exception(), 2, d, d);
b.Method2(d, d, new TypeC[]{d, d, d});
b.Method3(new int[6]{1, 2, 3, 4, 5, 6}, a, 8, 9, 10, 11, 12, 13, 14);
}
}";
var comp = CompileAndVerify(source,
expectedOutput: @"
Derived.Method( , 1, [1])
Derived.Method( , 2, [2])
Base.Method2( , , [3])
Derived.Method3([4], , [5])
Derived.Method3([6], , [7])
Class1.Method( , 2, [2])
Class1.Method2( , , [3])
Class1.Method3([6], , [7])",
expectedSignatures: new[]
{
Signature("NS.Derived", "Method", ".method public hidebysig newslot virtual final instance System.Int32 Method(System.Exception A, System.Int32 B, NS.Derived[] C) cil managed"),
Signature("NS.Base", "Method2", ".method public hidebysig newslot virtual final instance System.Void Method2(NS.Derived c1, NS.Derived c2, [System.ParamArrayAttribute()] NS.Derived[] C3) cil managed"),
Signature("NS.Derived", "Method3", ".method public hidebysig newslot virtual final instance System.Void Method3(System.Int32[] B1, Type`1[System.Int32] B2, [System.ParamArrayAttribute()] System.Int32[] b2) cil managed"),
Signature("NS.Class1", "Interface.Method", ".method private hidebysig newslot virtual final instance System.Int32 Interface.Method(System.Exception A, System.Int32 B, NS.Derived[] C) cil managed"),
Signature("NS.Class1", "Interface.Method2", ".method private hidebysig newslot virtual final instance System.Void Interface.Method2(NS.Derived c1, NS.Derived c2, NS.Derived[] C3) cil managed"),
Signature("NS.Class1", "Interface.Method3", ".method private hidebysig newslot virtual final instance System.Void Interface.Method3(System.Int32[] B1, Type`1[System.Int32] B2, [System.ParamArrayAttribute()] System.Int32[] B3) cil managed")
});
}
[Fact]
public void TestVBNestedInterfaceImplementationMetadata()
{
#region "Source"
var text1 = @"using System;
public class CINestedImpl : IMeth03.INested
{
public virtual void NestedSub(ushort p)
{
Console.Write(""ImpSub "");
}
public virtual string NestedFunc(ref object p)
{
Console.Write(""ImpFunc "");
return p.ToString();
}
void IMeth03.INested.NestedSub(ushort p)
{
Console.Write(""ExpSub "");
}
string IMeth03.INested.NestedFunc(ref object p)
{
Console.Write(""ExpFunc "");
return p.ToString();
}
}
";
var text2 = @"using System;
public class CINestedDerived : CINestedImpl, IMeth03.INested
{
public override void NestedSub(ushort p)
{
Console.Write(""ImpSubDerived "");
}
public new string NestedFunc(ref object p)
{
Console.Write(""ImpFuncDerived "");
return p.ToString();
}
void IMeth03.INested.NestedSub(ushort p)
{
Console.Write(""ExpSubDerived "");
}
string IMeth03.INested.NestedFunc(ref object p)
{
Console.Write(""ExpFuncDerived "");
return p.ToString();
}
}
";
var text3 = @"
class Test
{
static void Main()
{
CINestedDerived obj = new CINestedDerived();
CINestedImpl bobj = obj;
IMeth03.INested iobj = obj;
object o = obj;
obj.NestedSub(123);
obj.NestedFunc(ref o);
bobj.NestedSub(456);
bobj.NestedFunc(ref o);
iobj.NestedSub(789);
iobj.NestedFunc(ref o);
}
}
";
#endregion
var asmRef = TestReferences.MetadataTests.InterfaceAndClass.VBInterfaces01;
var comp1 = CreateCompilation(
text1,
references: new[] { asmRef },
assemblyName: "OHI_ExpImpImplVBNested001");
var comp2 = CreateCompilation(
text2,
references: new[] { asmRef, comp1.EmitToImageReference() },
assemblyName: "OHI_ExpImpImplVBNested002");
var comp3 = CreateCompilation(
text3,
references: new MetadataReference[] { asmRef, new CSharpCompilationReference(comp1), new CSharpCompilationReference(comp2) },
options: TestOptions.ReleaseExe,
assemblyName: "OHI_ExpImpImplVBNested003");
CompileAndVerify(comp3, expectedOutput: @"ImpSubDerived ImpFuncDerived ImpSubDerived ImpFunc ExpSubDerived ExpFuncDerived");
}
[Fact]
public void TestInterfaceMappingAcrossBaseClasses1()
{
var source = @"
using System;
interface Interface
{
void Method();
string Property { set; }
}
class Base
{
public void Method()
{
Console.WriteLine(""Base.Method"");
}
public string Property
{
get { return null; }
set { Console.WriteLine(""Base.Property""); }
}
}
class Derived : Base, Interface
{
void Interface.Method()
{
Console.WriteLine(""Derived.Interface.Method"");
}
string Interface.Property
{
set { Console.WriteLine(""Derived.Interface.Property""); }
}
}
class Derived2 : Derived
{
}
class Derived3 : Derived, Interface
{
}
class Test
{
public static void Main()
{
Interface i = new Derived();
i.Method();
i.Property = string.Empty;
i = new Derived2();
i.Method();
i.Property = string.Empty;
i = new Derived3();
i.Method();
i.Property = string.Empty;
}
}";
var comp = CompileAndVerify(source,
expectedOutput: @"
Derived.Interface.Method
Derived.Interface.Property
Derived.Interface.Method
Derived.Interface.Property
Derived.Interface.Method
Derived.Interface.Property",
expectedSignatures: new[]
{
Signature("Base", "Method", ".method public hidebysig instance System.Void Method() cil managed"),
Signature("Base", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed"),
Signature("Base", "set_Property", ".method public hidebysig specialname instance System.Void set_Property(System.String value) cil managed"),
Signature("Derived", "Interface.Method", ".method private hidebysig newslot virtual final instance System.Void Interface.Method() cil managed"),
Signature("Derived", "Interface.set_Property", ".method private hidebysig newslot specialname virtual final instance System.Void Interface.set_Property(System.String value) cil managed")
});
comp.VerifyDiagnostics(); // No errors
}
[Fact]
public void TestInterfaceMappingAcrossBaseClasses1A()
{
var source = @"
using System;
interface Interface
{
void Method();
string Property { set; }
}
class Base
{
public void Method()
{
Console.WriteLine(""Base.Method"");
}
public string Property
{
get { return null; }
set { Console.WriteLine(""Base.Property""); }
}
}
class Base1 : Base
{
}
class Derived : Base1, Interface
{
void Interface.Method()
{
Console.WriteLine(""Derived.Interface.Method"");
}
string Interface.Property
{
set { Console.WriteLine(""Derived.Interface.Property""); }
}
}
class Derived1 : Derived
{
}
class Derived2 : Derived1
{
}
class Derived3 : Derived1, Interface
{
}
class Test
{
public static void Main()
{
Interface i = new Derived();
i.Method();
i.Property = string.Empty;
i = new Derived2();
i.Method();
i.Property = string.Empty;
i = new Derived3();
i.Method();
i.Property = string.Empty;
}
}";
var comp = CompileAndVerify(source,
expectedOutput: @"
Derived.Interface.Method
Derived.Interface.Property
Derived.Interface.Method
Derived.Interface.Property
Derived.Interface.Method
Derived.Interface.Property",
expectedSignatures: new[]
{
Signature("Base", "Method", ".method public hidebysig instance System.Void Method() cil managed"),
Signature("Base", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed"),
Signature("Base", "set_Property", ".method public hidebysig specialname instance System.Void set_Property(System.String value) cil managed"),
Signature("Derived", "Interface.Method", ".method private hidebysig newslot virtual final instance System.Void Interface.Method() cil managed"),
Signature("Derived", "Interface.set_Property", ".method private hidebysig newslot specialname virtual final instance System.Void Interface.set_Property(System.String value) cil managed")
});
comp.VerifyDiagnostics(); // No errors
}
[Fact]
public void TestInterfaceMappingAcrossBaseClasses2()
{
var source = @"
using System;
interface Interface
{
void Method();
string Property { set; }
}
class Base : Interface
{
public void Method()
{
Console.WriteLine(""Base.Method"");
}
public string Property
{
get { return null; }
set { Console.WriteLine(""Base.Property""); }
}
}
class Derived : Base, Interface
{
void Interface.Method()
{
Console.WriteLine(""Derived.Interface.Method"");
}
string Interface.Property
{
set { Console.WriteLine(""Derived.Interface.Property""); }
}
}
class Derived2 : Derived
{
}
class Derived3 : Derived, Interface
{
}
class Test
{
public static void Main()
{
Interface i = new Derived();
i.Method();
i.Property = string.Empty;
i = new Derived2();
i.Method();
i.Property = string.Empty;
i = new Derived3();
i.Method();
i.Property = string.Empty;
}
}";
var comp = CompileAndVerify(source,
expectedOutput: @"
Derived.Interface.Method
Derived.Interface.Property
Derived.Interface.Method
Derived.Interface.Property
Derived.Interface.Method
Derived.Interface.Property",
expectedSignatures: new[]
{
Signature("Base", "Method", ".method public hidebysig newslot virtual final instance System.Void Method() cil managed"),
Signature("Base", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed"),
Signature("Base", "set_Property", ".method public hidebysig newslot specialname virtual final instance System.Void set_Property(System.String value) cil managed"),
Signature("Derived", "Interface.Method", ".method private hidebysig newslot virtual final instance System.Void Interface.Method() cil managed"),
Signature("Derived", "Interface.set_Property", ".method private hidebysig newslot specialname virtual final instance System.Void Interface.set_Property(System.String value) cil managed")
});
comp.VerifyDiagnostics(); // No errors
}
[Fact]
public void TestInterfaceMappingAcrossBaseClasses2A()
{
var source = @"
using System;
interface Interface
{
void Method();
string Property { set; }
}
class Base : Interface
{
public void Method()
{
Console.WriteLine(""Base.Method"");
}
public string Property
{
get { return null; }
set { Console.WriteLine(""Base.Property""); }
}
}
class Base1 : Base, Interface
{
}
class Derived : Base1, Interface
{
void Interface.Method()
{
Console.WriteLine(""Derived.Interface.Method"");
}
string Interface.Property
{
set { Console.WriteLine(""Derived.Interface.Property""); }
}
}
class Derived1 : Derived, Interface
{
}
class Derived2 : Derived1
{
}
class Derived3 : Derived1, Interface
{
}
class Test
{
public static void Main()
{
Interface i = new Derived();
i.Method();
i.Property = string.Empty;
i = new Derived2();
i.Method();
i.Property = string.Empty;
i = new Derived3();
i.Method();
i.Property = string.Empty;
}
}";
var comp = CompileAndVerify(source,
expectedOutput: @"
Derived.Interface.Method
Derived.Interface.Property
Derived.Interface.Method
Derived.Interface.Property
Derived.Interface.Method
Derived.Interface.Property",
expectedSignatures: new[]
{
Signature("Base", "Method", ".method public hidebysig newslot virtual final instance System.Void Method() cil managed"),
Signature("Base", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed"),
Signature("Base", "set_Property", ".method public hidebysig newslot specialname virtual final instance System.Void set_Property(System.String value) cil managed"),
Signature("Derived", "Interface.Method", ".method private hidebysig newslot virtual final instance System.Void Interface.Method() cil managed"),
Signature("Derived", "Interface.set_Property", ".method private hidebysig newslot specialname virtual final instance System.Void Interface.set_Property(System.String value) cil managed")
});
comp.VerifyDiagnostics(); // No errors
}
[WorkItem(540558, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540558")]
[WorkItem(540561, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540561")]
[Fact]
public void TestInterfaceMappingAcrossBaseClasses3()
{
var source = @"
using System;
interface Interface
{
void Method();
string Property { set; }
}
class Base : Interface
{
void Interface.Method()
{
Console.WriteLine(""Base.Interface.Method"");
}
string Interface.Property
{
set { Console.WriteLine(""Base.Interface.Property""); }
}
}
class Derived : Base
{
public void Method()
{
Console.WriteLine(""Derived.Method"");
}
public string Property
{
get { return null; }
set { Console.WriteLine(""Derived.Property""); }
}
}
class Derived2 : Derived
{
}
class Derived3 : Derived, Interface
{
}
class Test
{
public static void Main()
{
Interface i = new Derived();
i.Method();
i.Property = string.Empty;
i = new Derived2();
i.Method();
i.Property = string.Empty;
i = new Derived3();
i.Method();
i.Property = string.Empty;
}
}";
var comp = CompileAndVerify(source,
expectedOutput: @"
Base.Interface.Method
Base.Interface.Property
Base.Interface.Method
Base.Interface.Property
Derived.Method
Derived.Property",
expectedSignatures: new[]
{
Signature("Base", "Interface.Method", ".method private hidebysig newslot virtual final instance System.Void Interface.Method() cil managed"),
Signature("Base", "Interface.set_Property", ".method private hidebysig newslot specialname virtual final instance System.Void Interface.set_Property(System.String value) cil managed"),
// Implementing members in Derived should not be marked as virtual final
Signature("Derived", "Method", ".method public hidebysig instance System.Void Method() cil managed"),
Signature("Derived", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed"),
Signature("Derived", "set_Property", ".method public hidebysig specialname instance System.Void set_Property(System.String value) cil managed"),
// Stubs in Derived3 "call" corresponding members in Derived above
Signature("Derived3", "Interface.Method", ".method private hidebysig newslot virtual final instance System.Void Interface.Method() cil managed"),
Signature("Derived3", "Interface.set_Property", ".method private hidebysig newslot virtual final instance System.Void Interface.set_Property(System.String value) cil managed"),
});
comp.VerifyDiagnostics(); // No errors
// Stub should "call" Derived::Method / Derived::set_Property (even though we have another base class Derived1 in between)
comp.VerifyIL("Derived3.Interface.set_Property", @"{
// Code size 8 (0x8)
.maxstack 2
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: call ""void Derived.Property.set""
IL_0007: ret
}");
}
[WorkItem(540558, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540558")]
[WorkItem(540561, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540561")]
[Fact]
public void TestInterfaceMappingAcrossBaseClasses3A()
{
var source = @"
using System;
interface Interface
{
void Method();
string Property { set; }
}
class Base : Interface
{
void Interface.Method()
{
Console.WriteLine(""Base.Interface.Method"");
}
string Interface.Property
{
set { Console.WriteLine(""Base.Interface.Property""); }
}
}
class Base1 : Base
{
}
class Derived : Base1
{
public void Method()
{
Console.WriteLine(""Derived.Method"");
}
public string Property
{
get { return null; }
set { Console.WriteLine(""Derived.Property""); }
}
}
class Derived1 : Derived
{
}
class Derived2 : Derived1
{
}
class Derived3 : Derived1, Interface
{
}
class Test
{
public static void Main()
{
Interface i = new Derived();
i.Method();
i.Property = string.Empty;
i = new Derived2();
i.Method();
i.Property = string.Empty;
i = new Derived3();
i.Method();
i.Property = string.Empty;
}
}";
var comp = CompileAndVerify(source,
expectedOutput: @"
Base.Interface.Method
Base.Interface.Property
Base.Interface.Method
Base.Interface.Property
Derived.Method
Derived.Property",
expectedSignatures: new[]
{
Signature("Base", "Interface.Method", ".method private hidebysig newslot virtual final instance System.Void Interface.Method() cil managed"),
Signature("Base", "Interface.set_Property", ".method private hidebysig newslot specialname virtual final instance System.Void Interface.set_Property(System.String value) cil managed"),
// Implementing members in Derived should not be marked as virtual final
Signature("Derived", "Method", ".method public hidebysig instance System.Void Method() cil managed"),
Signature("Derived", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed"),
Signature("Derived", "set_Property", ".method public hidebysig specialname instance System.Void set_Property(System.String value) cil managed"),
// Stubs in Derived3 "call" corresponding members in Derived above
Signature("Derived3", "Interface.Method", ".method private hidebysig newslot virtual final instance System.Void Interface.Method() cil managed"),
Signature("Derived3", "Interface.set_Property", ".method private hidebysig newslot virtual final instance System.Void Interface.set_Property(System.String value) cil managed")
});
comp.VerifyDiagnostics(); // No errors
// Stub should "call" Derived::Method / Derived::set_Property (even though we have another base class Derived1 in between)
comp.VerifyIL("Derived3.Interface.set_Property", @"{
// Code size 8 (0x8)
.maxstack 2
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: call ""void Derived.Property.set""
IL_0007: ret
}");
}
[Fact]
public void TestInterfaceMappingAcrossBaseClasses4()
{
var source = @"
using System;
interface Interface
{
void Method();
string Property { set; }
}
class Base : Interface
{
void Interface.Method()
{
Console.WriteLine(""Base.Interface.Method"");
}
string Interface.Property
{
set { Console.WriteLine(""Base.Interface.Property""); }
}
}
class Derived : Base, Interface
{
public void Method()
{
Console.WriteLine(""Derived.Method"");
}
public string Property
{
get { return null; }
set { Console.WriteLine(""Derived.Property""); }
}
}
class Derived2 : Derived
{
}
class Derived3 : Derived, Interface
{
}
class Test
{
public static void Main()
{
Interface i = new Derived();
i.Method();
i.Property = string.Empty;
i = new Derived2();
i.Method();
i.Property = string.Empty;
i = new Derived3();
i.Method();
i.Property = string.Empty;
}
}";
var comp = CompileAndVerify(source,
expectedOutput: @"
Derived.Method
Derived.Property
Derived.Method
Derived.Property
Derived.Method
Derived.Property",
expectedSignatures: new[]
{
Signature("Base", "Interface.Method", ".method private hidebysig newslot virtual final instance System.Void Interface.Method() cil managed"),
Signature("Base", "Interface.set_Property", ".method private hidebysig newslot specialname virtual final instance System.Void Interface.set_Property(System.String value) cil managed"),
Signature("Derived", "Method", ".method public hidebysig newslot virtual final instance System.Void Method() cil managed"),
Signature("Derived", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed"),
Signature("Derived", "set_Property", ".method public hidebysig newslot specialname virtual final instance System.Void set_Property(System.String value) cil managed")
});
comp.VerifyDiagnostics(); // No errors
}
[Fact]
public void TestInterfaceMappingAcrossBaseClasses4A()
{
var source = @"
using System;
interface Interface
{
void Method();
string Property { set; }
}
class Base : Interface
{
void Interface.Method()
{
Console.WriteLine(""Base.Interface.Method"");
}
string Interface.Property
{
set { Console.WriteLine(""Base.Interface.Property""); }
}
}
class Base1 : Base, Interface
{
}
class Derived : Base1, Interface
{
public void Method()
{
Console.WriteLine(""Derived.Method"");
}
public string Property
{
get { return null; }
set { Console.WriteLine(""Derived.Property""); }
}
}
class Derived1 : Derived, Interface
{
}
class Derived2 : Derived1
{
}
class Derived3 : Derived1, Interface
{
}
class Test
{
public static void Main()
{
Interface i = new Derived();
i.Method();
i.Property = string.Empty;
i = new Derived2();
i.Method();
i.Property = string.Empty;
i = new Derived3();
i.Method();
i.Property = string.Empty;
}
}";
var comp = CompileAndVerify(source,
expectedOutput: @"
Derived.Method
Derived.Property
Derived.Method
Derived.Property
Derived.Method
Derived.Property",
expectedSignatures: new[]
{
Signature("Base", "Interface.Method", ".method private hidebysig newslot virtual final instance System.Void Interface.Method() cil managed"),
Signature("Base", "Interface.set_Property", ".method private hidebysig newslot specialname virtual final instance System.Void Interface.set_Property(System.String value) cil managed"),
Signature("Derived", "Method", ".method public hidebysig newslot virtual final instance System.Void Method() cil managed"),
Signature("Derived", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed"),
Signature("Derived", "set_Property", ".method public hidebysig newslot specialname virtual final instance System.Void set_Property(System.String value) cil managed")
});
comp.VerifyDiagnostics(); // No errors
}
[Fact]
public void TestInterfaceMappingAcrossBaseClasses5()
{
var source = @"
using System;
interface Interface
{
void Method();
string Property { set; }
}
class Base : Interface
{
void Interface.Method()
{
Console.WriteLine(""Base.Interface.Method"");
}
string Interface.Property
{
set { Console.WriteLine(""Base.Interface.Property""); }
}
public void Method()
{
Console.WriteLine(""Base.Method"");
}
public string Property
{
get { return null; }
set { Console.WriteLine(""Base.Property""); }
}
}
class Derived : Base
{
}
class Derived2 : Derived
{
}
class Derived3 : Derived, Interface
{
}
class Test
{
public static void Main()
{
Interface i = new Derived();
i.Method();
i.Property = string.Empty;
i = new Derived2();
i.Method();
i.Property = string.Empty;
i = new Derived3();
i.Method();
i.Property = string.Empty;
}
}";
var comp = CompileAndVerify(source,
expectedOutput: @"
Base.Interface.Method
Base.Interface.Property
Base.Interface.Method
Base.Interface.Property
Base.Interface.Method
Base.Interface.Property",
expectedSignatures: new[]
{
Signature("Base", "Interface.Method", ".method private hidebysig newslot virtual final instance System.Void Interface.Method() cil managed"),
Signature("Base", "Interface.set_Property", ".method private hidebysig newslot specialname virtual final instance System.Void Interface.set_Property(System.String value) cil managed"),
Signature("Base", "Method", ".method public hidebysig instance System.Void Method() cil managed"),
Signature("Base", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed"),
Signature("Base", "set_Property", ".method public hidebysig specialname instance System.Void set_Property(System.String value) cil managed")
});
comp.VerifyDiagnostics(); // No errors
}
[Fact]
public void TestInterfaceMappingAcrossBaseClasses5A()
{
var source = @"
using System;
interface Interface
{
void Method();
string Property { set; }
}
class Base : Interface
{
void Interface.Method()
{
Console.WriteLine(""Base.Interface.Method"");
}
string Interface.Property
{
set { Console.WriteLine(""Base.Interface.Property""); }
}
public void Method()
{
Console.WriteLine(""Base.Method"");
}
public string Property
{
get { return null; }
set { Console.WriteLine(""Base.Property""); }
}
}
class Base1 : Base
{
}
class Derived : Base1
{
}
class Derived1 : Derived
{
}
class Derived2 : Derived1
{
}
class Derived3 : Derived1, Interface
{
}
class Test
{
public static void Main()
{
Interface i = new Derived();
i.Method();
i.Property = string.Empty;
i = new Derived2();
i.Method();
i.Property = string.Empty;
i = new Derived3();
i.Method();
i.Property = string.Empty;
}
}";
var comp = CompileAndVerify(source,
expectedOutput: @"
Base.Interface.Method
Base.Interface.Property
Base.Interface.Method
Base.Interface.Property
Base.Interface.Method
Base.Interface.Property",
expectedSignatures: new[]
{
Signature("Base", "Interface.Method", ".method private hidebysig newslot virtual final instance System.Void Interface.Method() cil managed"),
Signature("Base", "Interface.set_Property", ".method private hidebysig newslot specialname virtual final instance System.Void Interface.set_Property(System.String value) cil managed"),
Signature("Base", "Method", ".method public hidebysig instance System.Void Method() cil managed"),
Signature("Base", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed"),
Signature("Base", "set_Property", ".method public hidebysig specialname instance System.Void set_Property(System.String value) cil managed")
});
comp.VerifyDiagnostics(); // No errors
}
[Fact]
public void TestInterfaceMappingAcrossBaseClasses6()
{
var source = @"
using System;
interface Interface
{
void Method();
string Property { set; }
}
class Base : Interface
{
void Interface.Method()
{
Console.WriteLine(""Base.Interface.Method"");
}
string Interface.Property
{
set { Console.WriteLine(""Base.Interface.Property""); }
}
public void Method()
{
Console.WriteLine(""Base.Method"");
}
public string Property
{
get { return null; }
set { Console.WriteLine(""Base.Property""); }
}
}
class Derived : Base, Interface
{
}
class Derived2 : Derived
{
}
class Derived3 : Derived, Interface
{
}
class Test
{
public static void Main()
{
Interface i = new Derived();
i.Method();
i.Property = string.Empty;
i = new Derived2();
i.Method();
i.Property = string.Empty;
i = new Derived3();
i.Method();
i.Property = string.Empty;
}
}";
var comp = CompileAndVerify(source,
expectedOutput: @"
Base.Interface.Method
Base.Interface.Property
Base.Interface.Method
Base.Interface.Property
Base.Interface.Method
Base.Interface.Property",
expectedSignatures: new[]
{
Signature("Base", "Interface.Method", ".method private hidebysig newslot virtual final instance System.Void Interface.Method() cil managed"),
Signature("Base", "Interface.set_Property", ".method private hidebysig newslot specialname virtual final instance System.Void Interface.set_Property(System.String value) cil managed"),
Signature("Base", "Method", ".method public hidebysig instance System.Void Method() cil managed"),
Signature("Base", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed"),
Signature("Base", "set_Property", ".method public hidebysig specialname instance System.Void set_Property(System.String value) cil managed")
});
comp.VerifyDiagnostics(); // No errors
}
[Fact]
public void TestInterfaceMappingAcrossBaseClasses6A()
{
var source = @"
using System;
interface Interface
{
void Method();
string Property { set; }
}
class Base : Interface
{
void Interface.Method()
{
Console.WriteLine(""Base.Interface.Method"");
}
string Interface.Property
{
set { Console.WriteLine(""Base.Interface.Property""); }
}
public void Method()
{
Console.WriteLine(""Base.Method"");
}
public string Property
{
get { return null; }
set { Console.WriteLine(""Base.Property""); }
}
}
class Base1 : Base, Interface
{
}
class Derived : Base1, Interface
{
}
class Derived1 : Derived, Interface
{
}
class Derived2 : Derived1
{
}
class Derived3 : Derived1, Interface
{
}
class Test
{
public static void Main()
{
Interface i = new Derived();
i.Method();
i.Property = string.Empty;
i = new Derived2();
i.Method();
i.Property = string.Empty;
i = new Derived3();
i.Method();
i.Property = string.Empty;
}
}";
var comp = CompileAndVerify(source,
expectedOutput: @"
Base.Interface.Method
Base.Interface.Property
Base.Interface.Method
Base.Interface.Property
Base.Interface.Method
Base.Interface.Property",
expectedSignatures: new[]
{
Signature("Base", "Interface.Method", ".method private hidebysig newslot virtual final instance System.Void Interface.Method() cil managed"),
Signature("Base", "Interface.set_Property", ".method private hidebysig newslot specialname virtual final instance System.Void Interface.set_Property(System.String value) cil managed"),
Signature("Base", "Method", ".method public hidebysig instance System.Void Method() cil managed"),
Signature("Base", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed"),
Signature("Base", "set_Property", ".method public hidebysig specialname instance System.Void set_Property(System.String value) cil managed")
});
comp.VerifyDiagnostics(); // No errors
}
[Fact]
public void TestInterfaceMappingAcrossBaseClasses7()
{
var source = @"
using System;
interface Interface
{
void Method();
string Property { set; }
}
class Base
{
public void Method()
{
Console.WriteLine(""Base.Method"");
}
public string Property
{
get { return null; }
set { Console.WriteLine(""Base.Property""); }
}
}
class Derived : Base, Interface
{
public new void Method()
{
Console.WriteLine(""Derived.Method"");
}
public new string Property
{
get { return null; }
set { Console.WriteLine(""Derived.Property""); }
}
}
class Derived2 : Derived
{
}
class Derived3 : Derived, Interface
{
}
class Test
{
public static void Main()
{
Interface i = new Derived();
i.Method();
i.Property = string.Empty;
i = new Derived2();
i.Method();
i.Property = string.Empty;
i = new Derived3();
i.Method();
i.Property = string.Empty;
}
}";
var comp = CompileAndVerify(source,
expectedOutput: @"
Derived.Method
Derived.Property
Derived.Method
Derived.Property
Derived.Method
Derived.Property",
expectedSignatures: new[]
{
Signature("Base", "Method", ".method public hidebysig instance System.Void Method() cil managed"),
Signature("Base", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed"),
Signature("Base", "set_Property", ".method public hidebysig specialname instance System.Void set_Property(System.String value) cil managed"),
Signature("Derived", "Method", ".method public hidebysig newslot virtual final instance System.Void Method() cil managed"),
Signature("Derived", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed"),
Signature("Derived", "set_Property", ".method public hidebysig newslot specialname virtual final instance System.Void set_Property(System.String value) cil managed")
});
comp.VerifyDiagnostics(); // No errors
}
[Fact]
public void TestInterfaceMappingAcrossBaseClasses7A()
{
var source = @"
using System;
interface Interface
{
void Method();
string Property { set; }
}
class Base
{
public void Method()
{
Console.WriteLine(""Base.Method"");
}
public string Property
{
get { return null; }
set { Console.WriteLine(""Base.Property""); }
}
}
class Base1 : Base
{
}
class Derived : Base1, Interface
{
public new void Method()
{
Console.WriteLine(""Derived.Method"");
}
public new string Property
{
get { return null; }
set { Console.WriteLine(""Derived.Property""); }
}
}
class Derived1 : Derived
{
}
class Derived2 : Derived1
{
}
class Derived3 : Derived1, Interface
{
}
class Test
{
public static void Main()
{
Interface i = new Derived();
i.Method();
i.Property = string.Empty;
i = new Derived2();
i.Method();
i.Property = string.Empty;
i = new Derived3();
i.Method();
i.Property = string.Empty;
}
}";
var comp = CompileAndVerify(source,
expectedOutput: @"
Derived.Method
Derived.Property
Derived.Method
Derived.Property
Derived.Method
Derived.Property",
expectedSignatures: new[]
{
Signature("Base", "Method", ".method public hidebysig instance System.Void Method() cil managed"),
Signature("Base", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed"),
Signature("Base", "set_Property", ".method public hidebysig specialname instance System.Void set_Property(System.String value) cil managed"),
Signature("Derived", "Method", ".method public hidebysig newslot virtual final instance System.Void Method() cil managed"),
Signature("Derived", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed"),
Signature("Derived", "set_Property", ".method public hidebysig newslot specialname virtual final instance System.Void set_Property(System.String value) cil managed")
});
comp.VerifyDiagnostics(); // No errors
}
[Fact]
public void TestInterfaceMappingAcrossBaseClasses8()
{
var source = @"
using System;
interface Interface
{
void Method();
string Property { set; }
}
class Base : Interface
{
public void Method()
{
Console.WriteLine(""Base.Method"");
}
public string Property
{
get { return null; }
set { Console.WriteLine(""Base.Property""); }
}
}
class Derived : Base, Interface
{
public new void Method()
{
Console.WriteLine(""Derived.Method"");
}
public new string Property
{
get { return null; }
set { Console.WriteLine(""Derived.Property""); }
}
}
class Derived2 : Derived
{
}
class Derived3 : Derived, Interface
{
}
class Test
{
public static void Main()
{
Interface i = new Derived();
i.Method();
i.Property = string.Empty;
i = new Derived2();
i.Method();
i.Property = string.Empty;
i = new Derived3();
i.Method();
i.Property = string.Empty;
}
}";
var comp = CompileAndVerify(source,
expectedOutput: @"
Derived.Method
Derived.Property
Derived.Method
Derived.Property
Derived.Method
Derived.Property",
expectedSignatures: new[]
{
Signature("Base", "Method", ".method public hidebysig newslot virtual final instance System.Void Method() cil managed"),
Signature("Base", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed"),
Signature("Base", "set_Property", ".method public hidebysig newslot specialname virtual final instance System.Void set_Property(System.String value) cil managed"),
Signature("Derived", "Method", ".method public hidebysig newslot virtual final instance System.Void Method() cil managed"),
Signature("Derived", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed"),
Signature("Derived", "set_Property", ".method public hidebysig newslot specialname virtual final instance System.Void set_Property(System.String value) cil managed"),
});
comp.VerifyDiagnostics(); // No errors
}
[Fact]
public void TestInterfaceMappingAcrossBaseClasses8A()
{
var source = @"
using System;
interface Interface
{
void Method();
string Property { set; }
}
class Base : Interface
{
public void Method()
{
Console.WriteLine(""Base.Method"");
}
public string Property
{
get { return null; }
set { Console.WriteLine(""Base.Property""); }
}
}
class Base1 : Base, Interface
{
}
class Derived : Base1, Interface
{
public new void Method()
{
Console.WriteLine(""Derived.Method"");
}
public new string Property
{
get { return null; }
set { Console.WriteLine(""Derived.Property""); }
}
}
class Derived1 : Derived, Interface
{
}
class Derived2 : Derived1
{
}
class Derived3 : Derived1, Interface
{
}
class Test
{
public static void Main()
{
Interface i = new Derived();
i.Method();
i.Property = string.Empty;
i = new Derived2();
i.Method();
i.Property = string.Empty;
i = new Derived3();
i.Method();
i.Property = string.Empty;
}
}";
var comp = CompileAndVerify(source,
expectedOutput: @"
Derived.Method
Derived.Property
Derived.Method
Derived.Property
Derived.Method
Derived.Property",
expectedSignatures: new[]
{
Signature("Base", "Method", ".method public hidebysig newslot virtual final instance System.Void Method() cil managed"),
Signature("Base", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed"),
Signature("Base", "set_Property", ".method public hidebysig newslot specialname virtual final instance System.Void set_Property(System.String value) cil managed"),
Signature("Derived", "Method", ".method public hidebysig newslot virtual final instance System.Void Method() cil managed"),
Signature("Derived", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed"),
Signature("Derived", "set_Property", ".method public hidebysig newslot specialname virtual final instance System.Void set_Property(System.String value) cil managed")
});
comp.VerifyDiagnostics(); // No errors
}
[Fact]
public void TestInterfaceMappingAcrossBaseClasses9()
{
var source = @"
using System;
interface Interface
{
void Method();
string Property { set; }
}
class Base : Interface
{
void Interface.Method()
{
Console.WriteLine(""Base.Interface.Method"");
}
string Interface.Property
{
set { Console.WriteLine(""Base.Interface.Property""); }
}
}
class Derived : Base, Interface
{
void Interface.Method()
{
Console.WriteLine(""Derived.Interface.Method"");
}
string Interface.Property
{
set { Console.WriteLine(""Derived.Interface.Property""); }
}
}
class Derived2 : Derived
{
}
class Derived3 : Derived, Interface
{
}
class Test
{
public static void Main()
{
Interface i = new Derived();
i.Method();
i.Property = string.Empty;
i = new Derived2();
i.Method();
i.Property = string.Empty;
i = new Derived3();
i.Method();
i.Property = string.Empty;
}
}";
var comp = CompileAndVerify(source,
expectedOutput: @"
Derived.Interface.Method
Derived.Interface.Property
Derived.Interface.Method
Derived.Interface.Property
Derived.Interface.Method
Derived.Interface.Property",
expectedSignatures: new[]
{
Signature("Base", "Interface.Method", ".method private hidebysig newslot virtual final instance System.Void Interface.Method() cil managed"),
Signature("Base", "Interface.set_Property", ".method private hidebysig newslot specialname virtual final instance System.Void Interface.set_Property(System.String value) cil managed"),
Signature("Derived", "Interface.Method", ".method private hidebysig newslot virtual final instance System.Void Interface.Method() cil managed"),
Signature("Derived", "Interface.set_Property", ".method private hidebysig newslot specialname virtual final instance System.Void Interface.set_Property(System.String value) cil managed")
});
comp.VerifyDiagnostics(); // No errors
}
[Fact]
public void TestInterfaceMappingAcrossBaseClasses9A()
{
var source = @"
using System;
interface Interface
{
void Method();
string Property { set; }
}
class Base : Interface
{
void Interface.Method()
{
Console.WriteLine(""Base.Interface.Method"");
}
string Interface.Property
{
set { Console.WriteLine(""Base.Interface.Property""); }
}
}
class Base1 : Base, Interface
{
}
class Derived : Base1, Interface
{
void Interface.Method()
{
Console.WriteLine(""Derived.Interface.Method"");
}
string Interface.Property
{
set { Console.WriteLine(""Derived.Interface.Property""); }
}
}
class Derived1 : Derived
{
}
class Derived2 : Derived1
{
}
class Derived3 : Derived1, Interface
{
}
class Test
{
public static void Main()
{
Interface i = new Derived();
i.Method();
i.Property = string.Empty;
i = new Derived2();
i.Method();
i.Property = string.Empty;
i = new Derived3();
i.Method();
i.Property = string.Empty;
}
}";
var comp = CompileAndVerify(source,
expectedOutput: @"
Derived.Interface.Method
Derived.Interface.Property
Derived.Interface.Method
Derived.Interface.Property
Derived.Interface.Method
Derived.Interface.Property",
expectedSignatures: new[]
{
Signature("Base", "Interface.Method", ".method private hidebysig newslot virtual final instance System.Void Interface.Method() cil managed"),
Signature("Base", "Interface.set_Property", ".method private hidebysig newslot specialname virtual final instance System.Void Interface.set_Property(System.String value) cil managed"),
Signature("Derived", "Interface.Method", ".method private hidebysig newslot virtual final instance System.Void Interface.Method() cil managed"),
Signature("Derived", "Interface.set_Property", ".method private hidebysig newslot specialname virtual final instance System.Void Interface.set_Property(System.String value) cil managed")
});
comp.VerifyDiagnostics(); // No errors
}
[Fact]
public void TestInterfaceMappingAcrossBaseClasses10()
{
var source = @"
using System;
interface Interface
{
void Method();
string Property { set; }
}
class Base : Interface
{
void Interface.Method()
{
Console.WriteLine(""Base.Interface.Method"");
}
string Interface.Property
{
set { Console.WriteLine(""Base.Interface.Property""); }
}
public void Method()
{
Console.WriteLine(""Base.Method"");
}
public string Property
{
get { return null; }
set { Console.WriteLine(""Base.Property""); }
}
}
class Derived : Base, Interface
{
void Interface.Method()
{
Console.WriteLine(""Derived.Interface.Method"");
}
string Interface.Property
{
set { Console.WriteLine(""Derived.Interface.Property""); }
}
public new void Method()
{
Console.WriteLine(""Derived.Method"");
}
public new string Property
{
get { return null; }
set { Console.WriteLine(""Derived.Property""); }
}
}
class Derived2 : Derived
{
}
class Derived3 : Derived, Interface
{
}
class Test
{
public static void Main()
{
Interface i = new Derived();
i.Method();
i.Property = string.Empty;
i = new Derived2();
i.Method();
i.Property = string.Empty;
i = new Derived3();
i.Method();
i.Property = string.Empty;
}
}";
var comp = CompileAndVerify(source,
expectedOutput: @"
Derived.Interface.Method
Derived.Interface.Property
Derived.Interface.Method
Derived.Interface.Property
Derived.Interface.Method
Derived.Interface.Property",
expectedSignatures: new[]
{
Signature("Base", "Interface.Method", ".method private hidebysig newslot virtual final instance System.Void Interface.Method() cil managed"),
Signature("Base", "Interface.set_Property", ".method private hidebysig newslot specialname virtual final instance System.Void Interface.set_Property(System.String value) cil managed"),
Signature("Base", "Method", ".method public hidebysig instance System.Void Method() cil managed"),
Signature("Base", "set_Property", ".method public hidebysig specialname instance System.Void set_Property(System.String value) cil managed"),
Signature("Base", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed"),
Signature("Derived", "Interface.Method", ".method private hidebysig newslot virtual final instance System.Void Interface.Method() cil managed"),
Signature("Derived", "Interface.set_Property", ".method private hidebysig newslot specialname virtual final instance System.Void Interface.set_Property(System.String value) cil managed"),
Signature("Derived", "Method", ".method public hidebysig instance System.Void Method() cil managed"),
Signature("Derived", "set_Property", ".method public hidebysig specialname instance System.Void set_Property(System.String value) cil managed"),
Signature("Derived", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed")
});
comp.VerifyDiagnostics(); // No errors
}
[Fact]
public void TestInterfaceMappingAcrossBaseClasses10A()
{
var source = @"
using System;
interface Interface
{
void Method();
string Property { set; }
}
class Base : Interface
{
void Interface.Method()
{
Console.WriteLine(""Base.Interface.Method"");
}
string Interface.Property
{
set { Console.WriteLine(""Base.Interface.Property""); }
}
public void Method()
{
Console.WriteLine(""Base.Method"");
}
public string Property
{
get { return null; }
set { Console.WriteLine(""Base.Property""); }
}
}
class Base1 : Base, Interface
{
}
class Derived : Base1, Interface
{
void Interface.Method()
{
Console.WriteLine(""Derived.Interface.Method"");
}
string Interface.Property
{
set { Console.WriteLine(""Derived.Interface.Property""); }
}
public new void Method()
{
Console.WriteLine(""Derived.Method"");
}
public new string Property
{
get { return null; }
set { Console.WriteLine(""Derived.Property""); }
}
}
class Derived1 : Derived, Interface
{
}
class Derived2 : Derived1
{
}
class Derived3 : Derived1, Interface
{
}
class Test
{
public static void Main()
{
Interface i = new Derived();
i.Method();
i.Property = string.Empty;
i = new Derived2();
i.Method();
i.Property = string.Empty;
i = new Derived3();
i.Method();
i.Property = string.Empty;
}
}";
var comp = CompileAndVerify(source,
expectedOutput: @"
Derived.Interface.Method
Derived.Interface.Property
Derived.Interface.Method
Derived.Interface.Property
Derived.Interface.Method
Derived.Interface.Property",
expectedSignatures: new[]
{
Signature("Base", "Interface.Method", ".method private hidebysig newslot virtual final instance System.Void Interface.Method() cil managed"),
Signature("Base", "Interface.set_Property", ".method private hidebysig newslot specialname virtual final instance System.Void Interface.set_Property(System.String value) cil managed"),
Signature("Base", "Method", ".method public hidebysig instance System.Void Method() cil managed"),
Signature("Base", "set_Property", ".method public hidebysig specialname instance System.Void set_Property(System.String value) cil managed"),
Signature("Base", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed"),
Signature("Derived", "Interface.Method", ".method private hidebysig newslot virtual final instance System.Void Interface.Method() cil managed"),
Signature("Derived", "Interface.set_Property", ".method private hidebysig newslot specialname virtual final instance System.Void Interface.set_Property(System.String value) cil managed"),
Signature("Derived", "Method", ".method public hidebysig instance System.Void Method() cil managed"),
Signature("Derived", "set_Property", ".method public hidebysig specialname instance System.Void set_Property(System.String value) cil managed"),
Signature("Derived", "get_Property", ".method public hidebysig specialname instance System.String get_Property() cil managed")
});
comp.VerifyDiagnostics(); // No errors
}
[Fact]
public void TestImplementAmbiguousSignaturesFromSameInterface()
{
// Tests:
// Implicitly / explicitly implement multiple base interface members (that have same signature) with a single member
// Implicitly / explicitly implement multiple base interface members (that have same signature) with a single member from base class
var source = @"
using System;
partial interface I1<T, U>
{
void Method<V>(T x, Func<U, T, V> v, U z);
}
class Implicit : I1<int, Int32>
{
public void Method<V>(int x, Func<int, int, V> v, int z) { }
}
partial interface I1<T, U>
{
void Method<Z>(U x, Func<T, U, Z> v, T z);
}
class Base
{
public void Method<V>(int x, Func<int, int, V> v, int z) { }
}
class Base2 : Base { }
class ImplicitInBase : Base2, I1<int, Int32> { }
class Explicit : I1<int, Int32>
{
void I1<Int32, Int32>.Method<V>(int x, Func<int, int, V> v, int z) { }
public void Method<V>(int x, Func<int, int, V> v, int z) { }
}
class Test
{
public static void Main()
{
I1<int, int> i = new Implicit();
i = new ImplicitInBase();
i = new Explicit();
}
}";
var comp = CompileAndVerify(source,
expectedOutput: "",
expectedSignatures: new[]
{
Signature("Implicit", "Method", ".method public hidebysig newslot virtual final instance System.Void Method<V>(System.Int32 x, System.Func`3[System.Int32,System.Int32,V] v, System.Int32 z) cil managed"),
Signature("Base", "Method", ".method public hidebysig newslot virtual final instance System.Void Method<V>(System.Int32 x, System.Func`3[System.Int32,System.Int32,V] v, System.Int32 z) cil managed"),
Signature("Explicit", "Method", ".method public hidebysig newslot virtual final instance System.Void Method<V>(System.Int32 x, System.Func`3[System.Int32,System.Int32,V] v, System.Int32 z) cil managed"),
Signature("Explicit", "I1<System.Int32,System.Int32>.Method", ".method private hidebysig newslot virtual final instance System.Void I1<System.Int32,System.Int32>.Method<V>(System.Int32 x, System.Func`3[System.Int32,System.Int32,V] v, System.Int32 z) cil managed")
});
comp.VerifyDiagnostics(
// (23,27): warning CS0473: Explicit interface implementation 'Explicit.I1<int, int>.Method<V>(int, System.Func<int, int, V>, int)' matches more than one interface member. Which interface member is actually chosen is implementation-dependent. Consider using a non-explicit implementation instead.
Diagnostic(ErrorCode.WRN_ExplicitImplCollision, "Method").WithArguments("Explicit.I1<int, int>.Method<V>(int, System.Func<int, int, V>, int)"));
}
[WorkItem(540581, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540581")]
[Fact]
public void TestImplementAmbiguousSignaturesFromDifferentInterfaces()
{
// Tests:
// Implicitly / explicitly implement multiple base interface members (that have same signature) with a single member
// Implicitly / explicitly implement multiple base interface members (that have same signature) with a single member from base class
var source = @"
using System;
interface I1<T>
{
void Method<V>(T x, Func<T, V> v);
Action<T> Property { get; set; }
}
interface I2<U>
{
void Method<Z>(U x, Func<U, Z> v);
Action<U> Property { get; set; }
}
interface I3<W> : I1<W>, I2<W>
{
void Method<Z>(W x, Func<W, Z> v);
Action<W> Property { get; set; }
}
class Implicit : I1<int>, I2<Int32>
{
public void Method<V>(int x, Func<int, V> v) { Console.WriteLine(""Implicit.Method""); }
public Action<int> Property
{
get { Console.WriteLine(""Implicit.get_Property""); return null; }
set { Console.WriteLine(""Implicit.set_Property""); }
}
}
class Implicit2 : I3<string>
{
public void Method<V>(string x, Func<string, V> v) { Console.WriteLine(""Implicit2.Method""); }
public Action<string> Property
{
get { Console.WriteLine(""Implicit2.get_Property""); return null; }
set { Console.WriteLine(""Implicit2.set_Property""); }
}
}
class Base
{
public void Method<V>(int x, Func<int, V> v) { Console.WriteLine(""Base.Method - int""); }
public void Method<V>(string x, Func<string, V> v) { Console.WriteLine(""Base.Method - string""); }
public Action<int> Property
{
get { Console.WriteLine(""Base.get_Property - int""); return null; }
set { Console.WriteLine(""Base.set_Property - int""); }
}
}
class Base2 : Base
{
public Action<string> Property
{
get { Console.WriteLine(""Base2.get_Property - string""); return null; }
set { Console.WriteLine(""Base2.set_Property - string""); }
}
}
class ImplicitInBase : Base2, I1<int>, I2<Int32> { }
class ImplicitInBase2 : Base2, I3<string> { }
class Explicit : I1<int>, I2<Int32>
{
void I1<Int32>.Method<V>(int x, Func<int, V> v) { Console.WriteLine(""Explicit.I1<int>.Method""); }
void I2<Int32>.Method<V>(int x, Func<int, V> v) { Console.WriteLine(""Explicit.I2<int>.Method""); }
Action<int> I1<int>.Property
{
get { Console.WriteLine(""Explicit.I1<int>.get_Property""); return null; }
set { Console.WriteLine(""Explicit.I1<int>.set_Property""); }
}
Action<int> I2<int>.Property
{
get { Console.WriteLine(""Explicit.I2<int>.get_Property""); return null; }
set { Console.WriteLine(""Explicit.I2<int>.set_Property""); }
}
}
class Explicit2 : I3<string>
{
void I1<string>.Method<V>(string x, Func<string, V> v) { Console.WriteLine(""Explicit2.I1<string>.Method""); }
void I2<string>.Method<V>(string x, Func<string, V> v) { Console.WriteLine(""Explicit2.I2<string>.Method""); }
void I3<string>.Method<V>(string x, Func<string, V> v) { Console.WriteLine(""Explicit2.I3<string>.Method""); }
Action<string> I1<string>.Property
{
get { Console.WriteLine(""Explicit2.I1<string>.get_Property""); return null; }
set { Console.WriteLine(""Explicit2.I1<string>.set_Property""); }
}
Action<string> I2<string>.Property
{
get { Console.WriteLine(""Explicit2.I2<string>.get_Property""); return null; }
set { Console.WriteLine(""Explicit2.I2<string>.set_Property""); }
}
Action<string> I3<string>.Property
{
get { Console.WriteLine(""Explicit2.I3<string>.get_Property""); return null; }
set { Console.WriteLine(""Explicit2.I3<string>.set_Property""); }
}
}
class Test
{
public static void Main()
{
I1<int> i = new Implicit();
Action<int> x = null;
i.Method<string>(1, null); i.Property = x; x = i.Property;
i = new ImplicitInBase();
i.Method<string>(1, null); i.Property = x; x = i.Property;
i = new Explicit();
i.Method<string>(1, null); i.Property = x; x = i.Property;
I2<int> j = new Implicit();
j.Method<string>(1, null); j.Property = x; x = j.Property;
j = new ImplicitInBase();
j.Method<string>(1, null); j.Property = x; x = j.Property;
j = new Explicit();
j.Method<string>(1, null); j.Property = x; x = j.Property;
I3<string> k = new Implicit2();
Action<string> y = null;
k.Method<string>("""", null); k.Property = y; y = k.Property;
k = new ImplicitInBase2();
k.Method<string>("""", null); k.Property = y; y = k.Property;
k = new Explicit2();
k.Method<string>("""", null); k.Property = y; y = k.Property;
}
}";
var comp = CompileAndVerify(source, expectedOutput: @"
Implicit.Method
Implicit.set_Property
Implicit.get_Property
Base.Method - int
Base.set_Property - int
Base.get_Property - int
Explicit.I1<int>.Method
Explicit.I1<int>.set_Property
Explicit.I1<int>.get_Property
Implicit.Method
Implicit.set_Property
Implicit.get_Property
Base.Method - int
Base.set_Property - int
Base.get_Property - int
Explicit.I2<int>.Method
Explicit.I2<int>.set_Property
Explicit.I2<int>.get_Property
Implicit2.Method
Implicit2.set_Property
Implicit2.get_Property
Base.Method - string
Base2.set_Property - string
Base2.get_Property - string
Explicit2.I3<string>.Method
Explicit2.I3<string>.set_Property
Explicit2.I3<string>.get_Property");
comp.VerifyDiagnostics(
// (15,10): warning CS0108: 'I3<W>.Method<Z>(W, System.Func<W, Z>)' hides inherited member 'I1<W>.Method<V>(W, System.Func<W, V>)'. Use the new keyword if hiding was intended.
Diagnostic(ErrorCode.WRN_NewRequired, "Method").WithArguments("I3<W>.Method<Z>(W, System.Func<W, Z>)", "I1<W>.Method<V>(W, System.Func<W, V>)"),
// (16,15): warning CS0108: 'I3<W>.Property' hides inherited member 'I1<W>.Property'. Use the new keyword if hiding was intended.
Diagnostic(ErrorCode.WRN_NewRequired, "Property").WithArguments("I3<W>.Property", "I1<W>.Property"),
// (48,27): warning CS0108: 'Base2.Property' hides inherited member 'Base.Property'. Use the new keyword if hiding was intended.
Diagnostic(ErrorCode.WRN_NewRequired, "Property").WithArguments("Base2.Property", "Base.Property"));
}
[WorkItem(540581, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540581")]
[Fact]
public void RegressionTestRefEmitBugRelatedToHidingInInterfaces()
{
var source = @"
using System;
interface I1<T>
{
void Method<V>(T x, Func<T, V> v);
Action<T> Property { get; set; }
}
interface I2<U>
{
void Method<Z>(U x, Func<U, Z> v);
Action<U> Property { get; set; }
}
interface I3<W> : I1<W>, I2<W>
{
void Method<Z>(W x, Func<W, Z> v);
Action<W> Property { get; set; }
}
class Implicit2 : I3<string>
{
public void Method<V>(string x, Func<string, V> v) { Console.WriteLine(""Implicit2.Method""); }
public Action<string> Property
{
get { Console.WriteLine(""Implicit2.get_Property""); return null; }
set { Console.WriteLine(""Implicit2.set_Property""); }
}
}
class Test
{
public static void Main()
{
I3<string> i = new Implicit2();
}
}";
CompileAndVerify(source, expectedOutput: "");
}
[Fact]
public void TestImplementUnambiguousSignaturesFromSameInterface()
{
var source = @"
using System;
interface Interface<S, T>
{
void Method();
void Method<T>(T x);
}
class Base
{
public void Method() { Console.WriteLine(""Base - Method""); }
}
class Implicit : Base, Interface<int, int>, Interface<string, string>
{
public void Method<T>(T x) { Console.WriteLine(""Implicit - Method<T>""); }
}
class Explicit : Interface<int, int>, Interface<string, string>
{
void Interface<int, int>.Method() { Console.WriteLine(""Explicit - Method - int""); }
void Interface<string, string>.Method() { Console.WriteLine(""Explicit - Method - string""); }
void Interface<int, int>.Method<T>(T x) { Console.WriteLine(""Explicit - Method<T> - int""); }
void Interface<string, string>.Method<V>(V x) { Console.WriteLine(""Explicit - Method<V> - string""); }
}
class Test
{
public static void Main()
{
Interface<int, int> i = new Explicit();
i.Method();
i.Method(1);
i.Method<string>("""");
i = new Implicit();
i.Method();
i.Method(1);
i.Method<string>("""");
}
}";
var comp = CompileAndVerify(source, expectedOutput: @"
Explicit - Method - int
Explicit - Method<T> - int
Explicit - Method<T> - int
Base - Method
Implicit - Method<T>
Implicit - Method<T>");
comp.VerifyDiagnostics(
// (6,17): warning CS0693: Type parameter 'T' has the same name as the type parameter from outer type 'Interface<S, T>'
Diagnostic(ErrorCode.WRN_TypeParameterSameAsOuterTypeParameter, "T").WithArguments("T", "Interface<S, T>")); // No errors
}
[Fact]
public void TestImplementAmbiguousSignaturesFromSameInterfaceImplicitlyAndExplicitly()
{
var source = @"
using System;
interface I1<T, U>
{
Action<T> Method(ref T x);
Action<U> Method(U x); // Omit ref
void Method(T x, U[] y);
void Method(U x, params T[] y); // Add params
long Method(T x, Func<T, U> v, U[] y);
int Method(U x, Func<T, U> v, params U[] y); // Add params and change return type
}
class Implicit : I1<int, int>
{
public Action<int> Method(ref int x) { Console.WriteLine(""Method(ref int x)""); return null; }
public Action<int> Method(int x) { Console.WriteLine(""Method(int x)""); return null; }
public void Method(int x, int[] y) { Console.WriteLine(""Method(int x, int[] y)""); }
// Implements both params and non-params version
public long Method(int x, Func<int, int> v, int[] y) { Console.WriteLine(""Method(int x, Func<int, int> v, int[] y)""); return 0; }
// We have to implement this explicitly
int I1<int, int>.Method(int x, Func<int, int> v, params int[] y) { Console.WriteLine(""I1<int, int>.Method(int x, Func<int, int> v, params int[] y)""); return 0; }
}
class Explicit : I1<int, int>
{
Action<int> I1<int, int>.Method(ref int x) { Console.WriteLine(""I1<int, int>.Method(ref int x)""); return null; }
Action<int> I1<int, int>.Method(int x) { Console.WriteLine(""I1<int, int>.Method(int x)""); return null; }
void I1<int, int>.Method(int x, int[] y) { Console.WriteLine(""I1<int, int>.Method(int x, int[] y)""); }
// This has to be implicit so as not to clash with the above
public void Method(int x, params int[] y) { Console.WriteLine(""Method(int x, params int[] y)""); }
long I1<int, int>.Method(int x, Func<int, int> v, int[] y) { Console.WriteLine(""long I1<int, int>.Method(int x, Func<int, int> v, int[] y)""); return 0; }
int I1<int, int>.Method(int x, Func<int, int> v, params int[] y) { Console.WriteLine(""int I1<int, int>.Method(int x, Func<int, int> v, params int[] y)""); return 0; }
}
class Test
{
public static void Main()
{
int x = 1; Func<int, int> y = null;
I1<int, int> i = new Implicit();
i.Method(ref x); i.Method(x);
i.Method(x, x, x, x);
i.Method(x, y, x, x, x);
i = new Explicit();
i.Method(ref x); i.Method(x);
i.Method(x, x, x, x);
i.Method(x, y, x, x, x);
}
}";
var comp = CompileAndVerify(source, expectedOutput: @"
Method(ref int x)
Method(int x)
Method(int x, int[] y)
I1<int, int>.Method(int x, Func<int, int> v, params int[] y)
I1<int, int>.Method(ref int x)
I1<int, int>.Method(int x)
Method(int x, params int[] y)
int I1<int, int>.Method(int x, Func<int, int> v, params int[] y)");
comp.VerifyDiagnostics(
// (26,23): warning CS0473: Explicit interface implementation 'Explicit.I1<int, int>.Method(int, int[])' matches more than one interface member. Which interface member is actually chosen is implementation-dependent. Consider using a non-explicit implementation instead.
Diagnostic(ErrorCode.WRN_ExplicitImplCollision, "Method").WithArguments("Explicit.I1<int, int>.Method(int, int[])"));
}
[Fact]
public void TestImplementAmbiguousSignaturesFromSameInterfaceImplicitlyInBaseClass()
{
var source = @"
using System;
interface I1<T, U>
{
Action<T> Method(ref T x);
Action<U> Method(U x); // Omit ref
void Method(ref Func<U, T> v);
void Method(out Func<T, U> v); // Toggle ref to out
void Method(T x, U[] y);
void Method(U x, params T[] y); // Add params
long Method(T x, Func<T, U> v, U[] y);
int Method(U x, Func<T, U> v, params U[] y); // Add params and change return type
}
class Base
{
public Action<int> Method(ref int x) { Console.WriteLine(""Method(ref int x)""); return null; }
public Action<int> Method(int x) { Console.WriteLine(""Method(int x)""); return null; }
public void Method(ref Func<int, int> v) { Console.WriteLine(""Method(ref Func<int, int> v)""); }
public void Method(int x, int[] y) { Console.WriteLine(""Method(int x, int[] y)""); }
public long Method(int x, Func<int, int> v, int[] y) { Console.WriteLine(""long Method(int x, Func<int, int> v, int[] y)""); return 0; }
}
class ImplicitInBase : Base, I1<int, int>
{
public void Method(out Func<int, int> v) { v = null; Console.WriteLine(""Method(out Func<int, int> v)""); }
public int Method(int x, Func<int, int> v, params int[] y) { Console.WriteLine(""int Method(int x, Func<int, int> v, params int[] y)""); return 0; }
}
class Test
{
public static void Main()
{
int x = 1; Func<int, int> y = null;
I1<int, int> i = new ImplicitInBase();
i.Method(ref x); i.Method(x); i.Method(ref y); i.Method(out y);
i.Method(x, x, x, x);
i.Method(x, y, x, x, x);
}
}";
var comp = CompileAndVerify(source, expectedOutput: @"
Method(ref int x)
Method(int x)
Method(out Func<int, int> v)
Method(out Func<int, int> v)
Method(int x, int[] y)
int Method(int x, Func<int, int> v, params int[] y)");
comp.VerifyDiagnostics(
// (25,16): warning CS0108: 'ImplicitInBase.Method(int, System.Func<int, int>, params int[])' hides inherited member 'Base.Method(int, System.Func<int, int>, int[])'. Use the new keyword if hiding was intended.
Diagnostic(ErrorCode.WRN_NewRequired, "Method").WithArguments("ImplicitInBase.Method(int, System.Func<int, int>, params int[])", "Base.Method(int, System.Func<int, int>, int[])"));
}
[WorkItem(540582, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540582")]
[Fact]
public void TestImplementNestedInterface()
{
var source = @"
using System;
public class Base
{
public int Method(long g) { Console.WriteLine(""Base.Method""); return 0;} // implicit in base
}
class C : Base, C.IX
{
public interface IX : C.IY
{
new void Method(int i);
}
public interface IY
{
void Method(int i);
int Method(long j);
int Property { set; }
}
public void Method(int i) { Console.WriteLine(""C.Method""); } // implicit
int IY.Property { set { Console.WriteLine(""C.IY.set_Property""); } } // explicit
public int Property { get { return 0; } set { Console.WriteLine(""C.set_Property""); } }
}
class U : U.I
{
public interface I
{
void Method(int i);
int Property { set; }
};
void I.Method(int i) { Console.WriteLine(""U.I.Method""); } // explicit
public int Property { set { Console.WriteLine(""U.set_Property""); } get { return 0; } } // implicit
}
class Test
{
public static void Main()
{
C.IX i = new C();
i.Method(1);
i.Method(1L);
i.Property = 0;
U.I j = new U();
j.Method(1);
j.Property = 0;
}
}";
CompileAndVerify(source, expectedOutput: @"
C.Method
Base.Method
C.IY.set_Property
U.I.Method
U.set_Property").VerifyDiagnostics(); // No errors
}
[Fact]
public void TestInterfaceMembersSignature()
{
var source = @"interface IFace
{
void Method();
int Prop { get; set; }
}";
var comp = CompileAndVerify(source, expectedSignatures: new[]
{
Signature("IFace", "Method", ".method public hidebysig newslot abstract virtual instance System.Void Method() cil managed"),
Signature("IFace", "get_Prop", ".method public hidebysig newslot specialname abstract virtual instance System.Int32 get_Prop() cil managed"),
Signature("IFace", "set_Prop", ".method public hidebysig newslot specialname abstract virtual instance System.Void set_Prop(System.Int32 value) cil managed"),
Signature("IFace", "Prop", ".property readwrite instance System.Int32 Prop")
});
}
[WorkItem(545625, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545625")]
[Fact]
public void ReverseArrayRankSpecifiersInExplicitImplementationName()
{
var source = @"
using System;
interface I<T>
{
void Goo();
}
class C : I<int[][,]>
{
static void Main()
{
I<int[][,]> x = new C();
Action a = x.Goo;
Console.WriteLine(a.Method);
}
void I<int[][,]>.Goo() { }
}
";
// NOTE: order reversed from C# notation.
CompileAndVerify(source, expectedOutput: @"Void I<System.Int32[,][]>.Goo()");
}
[Fact]
[WorkItem(530164, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530164"), WorkItem(531642, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/531642"), WorkItem(531643, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/531643")]
public void SynthesizedExplicitImplementationOfByRefReturn()
{
var il = @"
.class interface public abstract auto ansi I
{
.method public hidebysig newslot abstract virtual
instance int32& M() cil managed
{
}
} // end of class I
.class public auto ansi beforefieldinit B
extends [mscorlib]System.Object
{
.method public hidebysig instance int32&
M() cil managed
{
ldnull
throw
}
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
ldarg.0
call instance void [mscorlib]System.Object::.ctor()
ret
}
} // end of class B
";
var source = @"
public class D : B, I
{
}
";
var comp = CreateCompilationWithILAndMscorlib40(source, il, options: TestOptions.DebugDll);
var verifier = CompileAndVerify(comp, expectedSignatures: new[]
{
// NOTE: dev11 has the return type as void, which doesn't peverify.
Signature("D", "I.M", ".method private hidebysig newslot virtual final instance System.Int32& I.M() cil managed")
});
// NOTE: local optimized away even with optimizations turned off (since returning a ref local doesn't peverify).
verifier.VerifyIL("D.I.M", @"
{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call ""ref int B.M()""
IL_0006: ret
}
");
}
[Fact]
[WorkItem(530164, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530164")]
public void SynthesizedExplicitImplementationOfGenericByRefReturn()
{
var il = @"
.class interface public abstract auto ansi I`1<T>
{
.method public hidebysig newslot abstract virtual
instance !T& M1() cil managed
{
}
.method public hidebysig newslot abstract virtual
instance class I`1<!T[]>& M2() cil managed
{
}
.method public hidebysig newslot abstract virtual
instance !!U& M3<U>() cil managed
{
}
.method public hidebysig newslot abstract virtual
instance class I`1<!!U[]>& M4<U>() cil managed
{
}
} // end of class I`1
.class public auto ansi beforefieldinit B`1<T>
extends [mscorlib]System.Object
{
.method public hidebysig instance !T& M1() cil managed
{
ldnull
throw
}
.method public hidebysig instance class I`1<!T[]>&
M2() cil managed
{
ldnull
throw
}
.method public hidebysig instance !!U& M3<U>() cil managed
{
ldnull
throw
}
.method public hidebysig instance class I`1<!!U[]>&
M4<U>() cil managed
{
ldnull
throw
}
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
ldarg.0
call instance void [mscorlib]System.Object::.ctor()
ret
}
} // end of class B`1
";
var source = @"
public class D : B<char>, I<char>
{
}
";
var comp = CreateCompilationWithILAndMscorlib40(source, il, options: TestOptions.DebugDll);
var global = comp.GlobalNamespace;
var derivedType = global.GetMember<NamedTypeSymbol>("D");
var interfaceType = derivedType.Interfaces().Single();
Assert.Equal(global.GetMember<NamedTypeSymbol>("I"), interfaceType.OriginalDefinition);
var baseType = derivedType.BaseType();
Assert.Equal(global.GetMember<NamedTypeSymbol>("B"), baseType.OriginalDefinition);
var baseMethods = Enumerable.Range(1, 4).Select(i => baseType.GetMember<MethodSymbol>("M" + i)).ToArray();
var interfaceMethods = Enumerable.Range(1, 4).Select(i => interfaceType.GetMember<MethodSymbol>("M" + i)).ToArray();
AssertEx.Equal(baseMethods, interfaceMethods.Select(interfaceMethod => derivedType.FindImplementationForInterfaceMember(interfaceMethod)));
var verifier = CompileAndVerify(comp, expectedSignatures: new[]
{
// NOTE: dev11 has the return type as void, which doesn't peverify.
Signature("D", "I<System.Char>.M1", ".method private hidebysig newslot virtual final instance System.Char& I<System.Char>.M1() cil managed"),
Signature("D", "I<System.Char>.M2", ".method private hidebysig newslot virtual final instance I`1[System.Char[]]& I<System.Char>.M2() cil managed"),
Signature("D", "I<System.Char>.M3", ".method private hidebysig newslot virtual final instance U& I<System.Char>.M3<U>() cil managed"),
Signature("D", "I<System.Char>.M4", ".method private hidebysig newslot virtual final instance I`1[U[]]& I<System.Char>.M4<U>() cil managed"),
});
foreach (var pair in new[] { new[] { "1", "char" }, new[] { "2", "I<char[]>" }, new[] { "3<U>", "U" }, new[] { "4<U>", "I<U[]>" } })
{
// NOTE: local optimized away even with optimizations turned off (since returning a ref local doesn't peverify).
verifier.VerifyIL("D.I<char>.M" + pair[0], @"
{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: call ""ref " + pair[1] + " B<char>.M" + pair[0] + @"()""
IL_0006: ret
}
");
}
}
}
}
|