1

リフレクションを使用して、オブジェクトの正確な状態を表すすべてのメンバーを取得する必要があります。したがって、これらのメンバーにはフィールド ( FieldInfo) と自動プロパティ ( PropertyInfo) が含まれます。を使用してすべてのFieldInfos を取得できます

type.GetFields(); //ok some flags needed here

このリンクに記載されているように、自動実装されたプロパティを取得します。

public static bool MightBeCouldBeMaybeAutoGeneratedInstanceProperty(this PropertyInfo info)
{
    bool mightBe = info.GetGetMethod().HasCompilerGeneratedAttribute();
    if (!mightBe)
        return false;

    bool maybe = info.DeclaringType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
                                   .Where(f => f.Name.Contains(info.Name))
                                   .Where(f => f.Name.Contains("BackingField"))
                                   .Where(f => f.HasCompilerGeneratedAttribute())
                                   .Any();

    return maybe;
}

public static bool HasCompilerGeneratedAttribute(this MemberInfo mi)
{
    return mi.GetCustomAttributes(typeof(CompilerGeneratedAttribute), true).Any();
}

回答者が言うように、これは確かに脆いです。これを達成するためのより標準的な方法はありますか?私は考えています、多分何かとBindingFlagsそうですか?

type.GetMembers(BindingFlags....) ?
4

2 に答える 2

2

「オブジェクトの正確な状態」が単に含まれているすべてのインスタンス フィールドを意味する場合 (そうでない場合は明確にできますか?)、単一のステートメントでそれを実行できるはずです。宣言するフィールド間に大きな違いはありません。明示的に、およびコンパイラが追加する自動プロパティのバッキング フィールド。クラスを定義する場合:

public class FieldInfoTest
{
  private string testField;

  public string TestProperty { get; set; }
}

...それらすべてに一挙にアクセスできます

FieldInfo[] fields = typeof(FieldInfoTest).GetFields(BindingFlags.Instance |
                                                     BindingFlags.Public | 
                                                     BindingFlags.NonPublic);

foreach (var f in fields)
{
  Console.WriteLine(f.Name);
}

これにより、次の結果が得られます。

testField
<TestProperty>k__BackingField
于 2013-05-12T06:59:35.460 に答える
0

ジェレミーの答えは私が得ることができる最高のものです。別の選択肢があります(最初に質問自体で言及しました):

public static IEnumerable<MemberInfo> GetStateMembers(this Type t)
{
    return t.GetMembers(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
            .Where(m => m.MemberType == MemberTypes.Field && !((FieldInfo)m).Name.Contains('<')
                     || m.MemberType == MemberTypes.Property && ((PropertyInfo)m).IsAutoProperty());
}

public static bool IsAutoProperty(this PropertyInfo prop)
{
    if (!prop.CanWrite || !prop.CanRead)
        return false;

    return prop.DeclaringType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
                             .Any(f => f.Name.Contains("<" + prop.Name + ">"));
}

それがどのように機能するかについての詳細な説明: https://stackoverflow.com/a/16506710/661933

少しハックですが、これによりフィールドと自動プロパティが提供されます(フィールド情報のみを提供するジェレミーの回答とは異なります)。

于 2013-05-12T14:09:57.907 に答える