Ainsi, j'ai trouvé une solution pour obtenir un PropertyInfo avec une classe concrète et un PropertyInfo pour une interface implémentée par la classe concrète. Voici le code:Recherche de la propriété correcte implémentation d'une interface
public static PropertyInfo GetImplementingProperty(Type concreteType, PropertyInfo interfaceProperty)
{
// do some region parameter check, skipped
var interfaceType = interfaceProperty.DeclaringType;
//use the set method if we have a write only property
var getCorrectMethod = interfaceProperty.GetGetMethod() == null
? (Func<PropertyInfo, MethodInfo>) (p => p.GetSetMethod(true))
: p => p.GetGetMethod(true);
var propertyMethod = getCorrectMethod(interfaceProperty);
var mapping = concreteType.GetInterfaceMap(interfaceType);
MethodInfo targetMethod = null;
for (var i = 0; i < mapping.InterfaceMethods.Length; i++)
{
if (mapping.InterfaceMethods[i] == propertyMethod)
{
targetMethod = mapping.TargetMethods[i];
break;
}
}
foreach (var property in concreteType.GetProperties(
BindingFlags.Instance | BindingFlags.GetProperty |
BindingFlags.Public | BindingFlags.NonPublic)) // include non-public!
{
if (targetMethod == getCorrectMethod(property)) // include non-public!
{
return property;
}
}
throw new InvalidOperationException("The property {0} defined on the interface {1} has not been found on the class {2}. That should never happen."
.FormatText(interfaceProperty.Name, interfaceProperty.DeclaringType.FullName, concreteType.FullName));
}
Malheureusement, j'ai trouvé un cas où il échoue, et je ne sais pas comment résoudre ce problème. J'ai donc dans une dll une classe:
public abstract class BaseClass
{
public Guid ConfigId { get; set; }
public virtual Guid ConfigId2 { get; set; }
}
Puis dans un autre dll que je fais:
interface INamed
{
Guid ConfigId { get; }
Guid ConfigId2 { get; }
}
private class SuperClass : BaseClass, INamed
{
}
maintenant
ReflectionHelper.GetImplementingProperty(typeof(SuperClass), typeof(INamed).GetProperty("ConfigId2")); // this works
ReflectionHelper.GetImplementingProperty(typeof(SuperClass), typeof(INamed).GetProperty("ConfigId")); // this fails
Toute idée comment puis-je faire correspondre la propriété ConfigId à la définition de la propriété de la classe de base?
PS. J'ai des attributs sur les propriétés de la classe concrète, c'est pourquoi je dois les obtenir.
Toute aide appréciée!
Cela n'a aucun effet :( – MBoros