Reputation: 35
I have the following generic interface:
public interface IGenericInterface<T>
{
public void PrintGenericParameterTypeName()
{
Debug.Log($"Generic parameter type: {typeof(T).Name}");
}
}
I then have the following classes:
public class Base : MonoBehaviour, IGenericInterface<int>
{
}
public class Derived : Base, IGenericInterface<string>
{
}
I have an instance of type Derived
in my scene. When I run this code, I correctly get both of its generic interfaces (IGenericInterface<string>
and IGenericInterface<int>
)
var derived = FindObjectOfType<Derived>();
var derivedType = derived.GetType();
var derivedTypeGenericInterfaces =
derivedType.GetInterfaces()
.Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IGenericInterface<>));
However, when invoking the PrintGenericParameterTypeName
method for each of the interfaces, both times the method from the base class's interface implementation is invoked (IGenericInterface<int>
).
foreach (var genericInterface in derivedTypeGenericInterfaces)
{
var printMethod = genericInterface.GetMethod("PrintGenericParameterTypeName");
printMethod?.Invoke(derived, null);
}
Recreating this in a console application (the only difference being the Base
class does not inherit from anything) works as expected and the method is once invoked for IGenericInterface<string>
and once for IGenericInterface<int>
. In Unity, however, both times the method is invoked for IGenericInterface<int>
. Any ideas?
EDIT:
Changing the default interface method's return type to its generic type T
seems to have fixed the problem.
public T PrintGenericParameterTypeName()
{
Debug.Log($"Generic parameter type: {typeof(T).Name}");
return default;
}
And I am now getting the expected results. But I still have no explanation for this unexpected behavior.
Upvotes: 0
Views: 89
Reputation:
Try moving the implementation out of interface to the base class. Something like this...
public interface IGenericInterface<T>
{
abstract void PrintGenericParameterTypeName();
}
public class Base : IGenericInterface<int>
{
public void PrintGenericParameterTypeName()
{
Console.Write($"Generic parameter type: {typeof(T).Name}");
}
}
public class Derived : Base, IGenericInterface<string>
{
}
Then call it like this...
foreach (var i in derivedTypeGenericInterfaces)
{
i.InvokeMember("PrintGenericParameterTypeName",
BindingFlags.DeclaredOnly |
BindingFlags.Public |
BindingFlags.Instance | BindingFlags.InvokeMethod, null, derived, new object[] {});
}
Upvotes: 1