2015-12-21 1 views
0

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!

Répondre