Ho un tipo e un'interfaccia e ho bisogno di verificare che il tipo implementa l'interfaccia in modo astratto.Come verificare se un tipo .NET implementa in modo astratto determinate interfacce .NET?
Ho impostato per scrivere un codice forza bruto utilizzando Reflection ed è piuttosto brutto.
Mi chiedo se ci sia un modo migliore rispetto all'implementazione della forza bruta che sto facendo ora.
Qualche idea?
Grazie.
EDIT
non hanno ancora controllato l'attuazione, ma la forza progetto di codice bruta assomiglia a questo:
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;
}
senza compilarlo ho già vedo un problema con proprietà, che il codice ha per verificare se l'interfaccia definisce getter e/o setter e verificare i giusti metodi, invece di assumere ciecamente il getter. Ad ogni modo, come si può vedere, il codice è piuttosto noioso. Mi chiedo se c'è un modo migliore ...
EDIT 2
- desidero sottolineare, che questo è solo un progetto di implementazione, funziona per i casi semplici e si è rotto per più quelli complessi, come quando ci sono overload di metodi o metodi rinomina (non conosco VB, quindi non pensavo nemmeno fosse possibile). Ma sottolinea il mio punto che richiede molto lavoro per farlo nel modo giusto.
- Perché dovrei volere una cosa del genere? Abbiamo bisogno di creare tipi dinamicamente usando Reflection.Emit sulla base di determinati metadati acquisiti dinamicamente. Il tipo dinamico generato implementa determinate interfacce, ad esempio IDynamicObject, e potrebbe derivare da un tipo di antenato. Quel tipo di antenato è compilato staticamente. Fino a poco tempo fa, il tipo di antenato non era autorizzato a implementare l'interfaccia IDynamicObject. Data un'istanza del tipo dinamico, è necessario eseguirne il cast esplicito su IDynamicObject per ottenere l'accesso ai suoi metodi (ricorda che il tipo dinamico generato implementa l'interfaccia). Vorrei eliminare questi cast espliciti. L'unico modo per farlo è lasciare che il tipo di antenato implementa l'interfaccia IDynamicObject. Tuttavia, l'implementazione deve essere interamente astratta, che viene verificata dal codice di creazione del tipo dinamico. Ecco.
"codice forza bruta utilizzando Reflection" - puoi postarlo? –
cosa intendi esattamente quando dici "il tipo implementa l'interfaccia in modo astratto"? – LBushkin
OK, alcuni minuti per accertarsi che funzioni. – mark