public void GetInterfacesAndImplementationRelationships()
{
var tree = SyntaxTree.ParseText(@"
using System;
interface I1
{
void M1();
int P1 { get; set; }
}
interface I2 : I1
{
void M2();
}
class C1 : I1
{
public void M1() { }
public virtual int P1 { get; set; }
public void M2() { }
}
class C2 : C1, I2
{
new public void M1() { }
}
class C3 : C2, I1
{
public override int P1 { get; set; }
int I1.P1 { get; set; }
}");
var mscorlib = MetadataReference.CreateAssemblyReference("mscorlib");
var compilation = Compilation.Create("MyCompilation",
options: new CompilationOptions(OutputKind.DynamicallyLinkedLibrary),
syntaxTrees: new[] { tree }, references: new[] { mscorlib });
// Get TypeSymbols for types I1, I2, C1, C2 and C3 above.
TypeSymbol typeI1 = compilation.GetTypeByMetadataName("I1");
TypeSymbol typeI2 = compilation.GetTypeByMetadataName("I2");
TypeSymbol typeC1 = compilation.GetTypeByMetadataName("C1");
TypeSymbol typeC2 = compilation.GetTypeByMetadataName("C2");
TypeSymbol typeC3 = compilation.GetTypeByMetadataName("C3");
Assert.IsNull(typeI1.BaseType);
Assert.IsNull(typeI2.BaseType);
Assert.AreEqual(0, typeI1.Interfaces.Count);
Assert.IsTrue(typeI2.Interfaces.Single().Equals(typeI1));
// Get TypeSymbol for interface implemented by C1 above.
Assert.IsTrue(typeC1.Interfaces.Single().Equals(typeI1));
// Get TypeSymbols for interfaces implemented by C2 above.
Assert.IsTrue(typeC2.Interfaces.Single().Equals(typeI2));
Assert.AreEqual(2, typeC2.AllInterfaces.Count);
Assert.IsNotNull(typeC2.AllInterfaces.Single(type => type.Equals(typeI1)));
Assert.IsNotNull(typeC2.AllInterfaces.Single(type => type.Equals(typeI2)));
// Get TypeSymbols for interfaces implemented by C3 above.
Assert.IsTrue(typeC3.Interfaces.Single().Equals(typeI1));
Assert.AreEqual(2, typeC3.AllInterfaces.Count);
Assert.IsNotNull(typeC3.AllInterfaces.Single(type => type.Equals(typeI1)));
Assert.IsNotNull(typeC3.AllInterfaces.Single(type => type.Equals(typeI2)));
// Get MethodSymbols for methods named M1 and M2 in types I1, I2, C1 and C2 above.
var methodI1M1 = (MethodSymbol)typeI1.GetMembers("M1").Single();
var methodI2M2 = (MethodSymbol)typeI2.GetMembers("M2").Single();
var methodC1M1 = (MethodSymbol)typeC1.GetMembers("M1").Single();
var methodC1M2 = (MethodSymbol)typeC1.GetMembers("M2").Single();
var methodC2M1 = (MethodSymbol)typeC2.GetMembers("M1").Single();
// Get interface implementation relationships between above MethodSymbols.
Assert.IsTrue(typeC1.FindImplementationForInterfaceMember(methodI1M1).Equals(methodC1M1));
Assert.IsTrue(typeC2.FindImplementationForInterfaceMember(methodI1M1).Equals(methodC2M1));
Assert.IsTrue(typeC2.FindImplementationForInterfaceMember(methodI2M2).Equals(methodC1M2));
Assert.IsTrue(typeC3.FindImplementationForInterfaceMember(methodI1M1).Equals(methodC2M1));
Assert.IsTrue(typeC3.FindImplementationForInterfaceMember(methodI2M2).Equals(methodC1M2));
// Get PropertySymbols for properties named P1 in types I1, C1 and C3 above.
var propertyI1P1 = (PropertySymbol)typeI1.GetMembers("P1").Single();
var propertyC1P1 = (PropertySymbol)typeC1.GetMembers("P1").Single();
var propertyC3P1 = (PropertySymbol)typeC3.GetMembers("P1").Single();
var propertyC3I1P1 = (PropertySymbol)typeC3.GetMembers("I1.P1").Single();
// Get interface implementation relationships between above PropertySymbols.
Assert.IsTrue(typeC1.FindImplementationForInterfaceMember(propertyI1P1).Equals(propertyC1P1));
Assert.IsTrue(typeC2.FindImplementationForInterfaceMember(propertyI1P1).Equals(propertyC1P1));
Assert.IsTrue(typeC3.FindImplementationForInterfaceMember(propertyI1P1).Equals(propertyC3I1P1));
Assert.IsFalse(typeC3.FindImplementationForInterfaceMember(propertyI1P1).Equals(propertyC3P1));
Assert.IsTrue(propertyC3I1P1.ExplicitInterfaceImplementations.Single().Equals(propertyI1P1));
}