27

より具体的には、私が持っている場合:

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;
    }
}

リフレクションを使用して、TempInterface を明示的に実装するプロパティのすべての propertyInfos を取得するにはどうすればよいですか?

ありがとう。

4

9 に答える 9

4

このブログ投稿に記載されている実装に基づいて修正されたソリューションを次に示します。

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);
于 2008-11-11T01:40:37.570 に答える
4

明示的に実装されたインターフェイス プロパティのプロパティ getter および setter には、異常な属性があります。シール クラスのメンバーではない場合でも、IsFinal プロパティは True です。このコードを試して、私の主張を確認してください。

  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);
      }
    }
  }
于 2008-11-10T20:56:43.867 に答える
3

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;
于 2011-06-30T03:06:47.203 に答える
1

役立つ可能性のある単純なヘルパークラス:

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]; }
    }
}

明示的に実装されている場合でも、各インターフェイスのプロパティを取得します。

于 2012-04-17T13:05:35.040 に答える
1

ジェイコブ・カーペンターの答えを変更する必要がありましたが、うまく機能します。nobugz も動作しますが、Jacobs の方がコンパクトです。

var explicitProperties =
from method in typeof(TempClass).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
where method.IsFinal && method.IsPrivate
select method;
于 2009-05-11T14:45:51.193 に答える
1

複雑すぎる。インターフェイス型のメソッド/プロパティを熟考し、それらがクラス型に存在するかどうかを確認し、それらを比較して、存在する場合に「同じ」かどうかを確認する必要があります。

何かがインターフェイスにあるが、テストしている型ではない場合、それは明示的な実装です。両方にあるが、2 つの間で異なる場合、それは明示的なインターフェイスです。

于 2008-11-10T20:13:47.777 に答える
0

明らかな理由もなく、これは少し痛いようです。

私の解決策は、探しているプロパティの名前がわかっている場合で、非常に簡単です。

このケースを追加する必要があったリフレクションを少し簡単にするためのクラスがあります。

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 には、プライベート プロパティを取得するための両方の検索フラグが必要です。

于 2011-10-24T16:20:47.037 に答える
0

ジェイコブのコードにはフィルターがありません:

        var props = typeof(TempClass).GetInterfaces().Where(i => i.Name=="TempInterface").SelectMany(i => i.GetProperties());
        foreach (var prop in props)
            Console.WriteLine(prop);
于 2008-11-10T20:40:36.473 に答える