Tengo un tipo y una interfaz y necesito verificar que el tipo implemente la interfaz de manera abstracta.¿Cómo comprobar si un tipo .NET implementa cierta interfaz .NET de forma abstracta?
He configurado para escribir un código de fuerza bruta usando Reflection y es bastante feo.
Me pregunto si hay una forma mejor que la implementación de la fuerza bruta que estoy haciendo ahora.
¿Alguna idea?
Gracias.
EDITAR
no ha comprobado la aplicación todavía, pero la fuerza de tiro código bruta se parece a esto:
public static bool IsAbstractInterfaceImplementation(Type someType, Type someInterface)
{
if (!someInterface.IsAssignableFrom(someType))
{
return false;
}
if (!someType.IsAbstract)
{
return false;
}
var m_interfaceMemberNames = someInterface.GetMembers().Select(m => m.Name).ToList();
// Make sure every interface member implementation is abstract.
foreach (var typeMember in someType.FindMembers(MemberTypes.Event | MemberTypes.Property | MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance, null, null))
{
if (m_interfaceMemberNames.Contains(typeMember.Name))
{
MethodInfo method;
// Make sure the ancestor member is abstract.
switch (typeMember.MemberType)
{
case MemberTypes.Event:
if (!IsAbstractImplementation(((EventInfo)typeMember).GetAddMethod()))
{
return false;
}
method = ((EventInfo)typeMember).GetRemoveMethod();
break;
case MemberTypes.Property:
method = ((PropertyInfo)typeMember).GetGetMethod();
default:
method = (MethodInfo)typeMember;
break;
}
if (!IsAbstractImplementation(method))
{
return false;
}
}
}
return true;
}
public static bool IsAbstractImplementation(MethodInfo methodInfo)
{
const MethodAttributes expectedAttributes =
MethodAttributes.Abstract |
MethodAttributes.Public |
MethodAttributes.NewSlot |
MethodAttributes.Virtual;
return (methodInfo.Attributes & expectedAttributes) == expectedAttributes;
}
Sin compilación ya veo un problema con propiedades, que el código tiene para verificar si la interfaz define getter y/o setter y verificar el (los) método (s) correcto (s), en lugar de asumir ciegamente el getter. De todos modos, como se puede ver, el código es bastante aburrido. Me pregunto si hay una manera mejor ...
EDITAR 2
- que deseo destacar, que esto es sólo un proyecto de aplicación, que funciona en los casos simples y se rompe para obtener más complejos, como cuando hay sobrecargas de métodos o renombra el método (no sé VB, así que ni siquiera pensé que fuera posible). Pero enfatiza mi punto de que requiere mucho trabajo para hacerlo bien.
- ¿Por qué querría tal cosa? Necesitamos crear tipos dinámicamente usando Reflection.Emit basado en ciertos metadatos adquiridos dinámicamente. El tipo dinámico generado implementa cierta interfaz, digamos IDynamicObject, y puede derivar de algún tipo de ancestro. Ese tipo de antepasado está compilado estáticamente. Hasta hace poco, el tipo ancestro no tenía permitido implementar la interfaz IDynamicObject. Dado un ejemplo del tipo dinámico, uno tenía que lanzarlo explícitamente a IDynamicObject para obtener acceso a sus métodos (recuerde que el tipo dinámico generado implementa la interfaz). Me gustaría eliminar estos moldes explícitos. La única forma de hacerlo es dejar que el tipo ancestro implemente la interfaz IDynamicObject. Sin embargo, la implementación debe ser todo abstracta, que se verifica mediante el código de creación de tipo dinámico. Voila.
"código de fuerza bruta usando Reflection" - ¿puedes publicarlo? –
¿Qué quieres decir exactamente cuando dices "el tipo implementa la interfaz de manera abstracta"? – LBushkin
OK, unos minutos para asegurarse de que funciona en absoluto. – mark