He creado este método de extensión para verificar si un tipo implementa una interfaz. Para que funcione correctamente necesita comparar 2 tipos. Sin embargo, esta comparación no parece funcionar de manera confiable:
public static bool ImplementsInterface(this Type type, Type testInterface) { if (testInterface.GenericTypeArguments.Length > 0) { return testInterface.IsAssignableFrom(type); } else { foreach (var @interface in type.GetInterfaces()) { // This doesn't always work: if (@interface == testInterface) // But comparing the names instead always works! // if (@interface.Name == testInterface.Name) { return true; } } return false; } }
Este es el caso donde mi comparación falla:
public static class TestInterfaceExtensions { interface I1 { } interface I2<T> : I1 { } class Class1Int : I2<int> { } [Fact] public void ImplementsInterface() { Assert.True(typeof(Class1Int).ImplementsInterface(typeof(I2<>))); } }
Como se menciona en el comentario, si comparo los nombres de los tipos, siempre funciona como se esperaba. Me gustaría saber qué está pasando aquí.
Si la interfaz es genérica, debe compararla con la definición de tipo genérico:
public static bool ImplementsInterface(this Type type, Type testInterface) { if (testInterface.GenericTypeArguments.Length > 0) { return testInterface.IsAssignableFrom(type); } else { foreach (var @interface in type.GetInterfaces()) { var compareType = @interface.IsGenericType ? @interface.GetGenericTypeDefinition() : @interface; if (compareType == testInterface) { return true; } } return false; } }
Esto funciona para un montón de casos de prueba:
Console.WriteLine(typeof(Class1Int).ImplementsInterface(typeof(I2<>))); // True Console.WriteLine(typeof(Class1Int).ImplementsInterface(typeof(I2<int>))); // True Console.WriteLine(typeof(Class1Int).ImplementsInterface(typeof(I2<bool>))); // False Console.WriteLine(typeof(Class1Int).ImplementsInterface(typeof(I1))); // True Console.WriteLine(typeof(Class1Int).ImplementsInterface(typeof(I3))); // False
Ejemplo en vivo: https://dotnetfiddle.net/bBslxH