كيف يمكنني استخدام انعكاس للحصول على خصائص صراحة تنفيذ واجهة؟

StackOverflow https://stackoverflow.com/questions/278997

سؤال

وبشكل أكثر تحديدا، إذا كان لدي:

public class TempClass : TempInterface
{

    int TempInterface.TempProperty
    {
        get;
        set;
    }
    int TempInterface.TempProperty2
    {
        get;
        set;
    }

    public int TempProperty
    {
        get;
        set;
    }
}

public interface TempInterface
{
    int TempProperty
    {
        get;
        set;
    }
    int TempProperty2
    {
        get;
        set;
    }
}

وكيف يمكنني استخدام انعكاس للحصول على كل propertyInfos للعقارات تنفيذ صراحة TempInterface؟

وشكرا.

هل كانت مفيدة؟

المحلول 5

وكان لي لتعديل الجواب يعقوب نجار لكنه يعمل بشكل جيد. nobugz أيضا يعمل ولكن جاكوبس هو أكثر إحكاما.

var explicitProperties =
from method in typeof(TempClass).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
where method.IsFinal && method.IsPrivate
select method;

نصائح أخرى

وأعتقد أن درجة التي تبحث عنها غير System.Reflection.InterfaceMapping.

Type ifaceType = typeof(TempInterface);
Type tempType = typeof(TempClass);
InterfaceMapping map = tempType.GetInterfaceMap(ifaceType);
for (int i = 0; i < map.InterfaceMethods.Length; i++)
{
    MethodInfo ifaceMethod = map.InterfaceMethods[i];
    MethodInfo targetMethod = map.TargetMethods[i];
    Debug.WriteLine(String.Format("{0} maps to {1}", ifaceMethod, targetMethod));
}

ووجالبة الممتلكات واضع من خاصية واجهة تنفيذها بشكل واضح لديه سمة غير عادية. انها ممتلكات IsFinal هو صحيح، حتى عندما لا يكون عضوا في فئة مغلقة. حاول هذا الرمز للتحقق من تأكيدي:

  foreach (AssemblyName name in Assembly.GetEntryAssembly().GetReferencedAssemblies()) {
    Assembly asm = Assembly.Load(name);
    foreach (Type t in asm.GetTypes()) {
      if (t.IsAbstract) continue;
      foreach (MethodInfo mi in t.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)) {
        int dot = mi.Name.LastIndexOf('.');
        string s = mi.Name.Substring(dot + 1);
        if (!s.StartsWith("get_") && !s.StartsWith("set_")) continue;
        if (mi.IsFinal)
          Console.WriteLine(mi.Name);
      }
    }
  }

وهنا حل المعدلة على أساس التنفيذ الواردة في <لأ href = "http://weblogs.asp.net/rosherove/archive/2008/10/15/use-reflection-to-find-methods-that- تنفيذ-صريح-interfaces.aspx "يختلط =" نوفولو noreferrer "> هذا بلوق وظيفة :

var explicitProperties =
    from prop in typeof(TempClass).GetProperties(
        BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)
    let getAccessor = prop.GetGetMethod(true)
    where getAccessor.IsFinal && getAccessor.IsPrivate
    select prop;

foreach (var p in explicitProperties)
    Console.WriteLine(p.Name);

وبناء على في الإجابة من طرف MrKurt :

var targetMethods =
    from iface in typeof(TempClass).GetInterfaces()
    from method in typeof(TempClass).GetInterfaceMap(iface).TargetMethods
    select method;

var explicitProps =
    from prop in typeof(TempClass).GetProperties(BindingFlags.Instance |
                                                 BindingFlags.NonPublic)
    where targetMethods.Contains(prop.GetGetMethod(true)) ||
          targetMethods.Contains(prop.GetSetMethod(true))
    select prop;

وانه امر معقد للغاية. عليك أن تعكس على الأساليب / خصائص واجهة نوع، معرفة ما إذا كانت موجودة في نوع صفك، ومقارنتها لمعرفة ما اذا انهم "نفس" عندما لا وجود لها.

وإذا كان شيء ما في واجهة ولكن ليس من النوع الذي كنت اختبار، انها تنفيذ صريح. لو كان في كليهما، ولكن الفرق بين الاثنين، انها واجهة واضحة.

وكود يعقوب مفقود مرشح:

        var props = typeof(TempClass).GetInterfaces().Where(i => i.Name=="TempInterface").SelectMany(i => i.GetProperties());
        foreach (var prop in props)
            Console.WriteLine(prop);

وهذا يبدو مؤلما قليلا دون سبب واضح!

وبلدي الحل يكمن في حالة ما إذا كنت تعرف اسم الخاصية التي تبحث عن وبسيط جدا.

ولدي فئة لجعل انعكاس أسهل قليلا أن أود فقط أن إضافة هذه الحالة إلى:

public class PropertyInfoWrapper
{
    private readonly object _parent;
    private readonly PropertyInfo _property;

    public PropertyInfoWrapper(object parent, string propertyToChange)
    {
        var type = parent.GetType();
        var privateProperties= type.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance);

        var property = type.GetProperty(propertyToChange) ??
                       privateProperties.FirstOrDefault(p => UnQualifiedNameFor(p) == propertyName);

        if (property == null)
            throw new Exception(string.Format("cant find property |{0}|", propertyToChange));

        _parent = parent;
        _property = property;
    }

    private static string UnQualifiedNameFor(PropertyInfo p)
    {
        return p.Name.Split('.').Last();
    }

    public object Value
    {
        get { return _property.GetValue(_parent, null); }
        set { _property.SetValue(_parent, value, null); }
    }
}

وأنت غير قادر على مجرد القيام == على الاسم لخصائص تنفذ بشكل صريح لها أسماء مؤهل بشكل كامل.

وGetProperties يحتاج كل من أعلام البحث للحصول على الممتلكات الخاصة.

وهناك فئة المساعد البسيطة التي يمكن أن تساعد على:

public class InterfacesPropertiesMap
{
    private readonly Dictionary<Type, PropertyInfo[]> map;

    public InterfacesPropertiesMap(Type type)
    {
        this.Interfaces = type.GetInterfaces();
        var properties = type.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);

        this.map = new Dictionary<Type, PropertyInfo[]>(this.Interfaces.Length);

        foreach (var intr in this.Interfaces)
        {
            var interfaceMap = type.GetInterfaceMap(intr);
            this.map.Add(intr, properties.Where(p => interfaceMap.TargetMethods
                                                    .Any(t => t == p.GetGetMethod(true) ||
                                                              t == p.GetSetMethod(true)))
                                         .Distinct().ToArray());
        }
    }

    public Type[] Interfaces { get; private set; }

    public PropertyInfo[] this[Type interfaceType]
    {
        get { return this.map[interfaceType]; }
    }
}

وستحصل على خصائص كل واجهة، حتى تنفذ بشكل واضح.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top