Given the following interface that forces classes to implement a static method...
public interface IMyInterface<T>
{
static abstract int GetNumber();
}
And two classes that both have two implementations of IMyInterfacee<T>
public class MyClass1 : IMyInterface<Company>, IMyInterface<Person>
{
static int IMyInterface<Company>.GetNumber() => 1;
static int IMyInterface<Person>.GetNumber() => 2;
}
public class MyClass2 : IMyInterface<Company>, IMyInterface<Person>
{
static int IMyInterface<Company>.GetNumber() => 3;
static int IMyInterface<Person>.GetNumber() => 4;
}
When I have a method in a consuming class like this
public int GetNumbers(Type classType, Type genericType)
{
Type interfaceType = typeof(IMyInterface<>).MakeGenericType(genericType);
return ??????
}
How would I implement GetNumbers
so that I can call it like so
GetNumbers(typeof(MyClass1), typeof(Company)); // returns 1
GetNumbers(typeof(MyClass1), typeof(Person)); // returns 2
GetNumbers(typeof(MyClass2), typeof(Company)); // returns 3
GetNumbers(typeof(MyClass2), typeof(Person)); // returns 3
CodePudding user response:
You can use interface mapping (Type.GetInterfaceMap
) to find the method which implements the interface:
int GetNumbers(Type classType, Type genericType)
{
Type interfaceType = typeof(IMyInterface<>).MakeGenericType(genericType);
// todo - check that class implements interface
var interfaceMapping = classType.GetInterfaceMap(interfaceType);
MethodInfo? methodInfo = null;
for (int i = 0; i < interfaceMapping.InterfaceMethods.Length; i )
{
var sourceMethod = interfaceMapping.InterfaceMethods[i];
// simple predicate to find by name
// possibly check that parameters are empty and return type is int
if (sourceMethod.Name.Equals(nameof(IMyInterface<object>.GetNumber), StringComparison.Ordinal))
{
methodInfo = interfaceMapping.TargetMethods[i];
break;
}
}
if (methodInfo is null)
{
throw new Exception("Should not happen");
}
return (int)methodInfo.Invoke(null, null);
}