2015年2月11日

プロパティのアクセシビリティと PropertyInfo

PropertyInfo を取得する際、アクセシビリティで混乱したので調査。

プロパティ定義 GetProperties の引数 BindingFlags PropertyInfo 情報
get
アクセサ
set
アクセサ
CanRead CanWrite GetMethod
.Attributes
SetMethod
.Attributes
public public Public Public Public
public private Public Public Private
private public Public Private Public
public - Public Public -
- public Public - Public
protected protected NonPublic Family Family
internal internal NonPublic Assembly Assembly
protected
internal
protected
internal
NonPublic FamORAssem FamORAssem
private private NonPublic Private Private
private - NonPublic Private -
- private NonPublic - Private
※GetMethod と SetMethod の MethodBase.Attributes は、Public/Private/Family/Assembly/FamORAssem
のみ抽出

[調査コード]

class Program
{
    static void Main(string[] args)
    {
        ShowPropInfo(new Props());
    }
    static void ShowPropInfo<T>(T source)
    {
        var t = typeof(T);
        Console.WriteLine("[Public]");
        ShowPropDetail(t.GetProperties(BindingFlags.Instance | BindingFlags.Public));

        Console.WriteLine();

        Console.WriteLine("[NonPublic]");
        ShowPropDetail(t.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic));
    }
    static void ShowPropDetail(IEnumerable<PropertyInfo> props)
    {
        foreach( var prop in props ){
            Console.WriteLine("Name:{0} CanRead:{1} CanWrite:{2}",
                prop.Name, prop.CanRead, prop.CanWrite);

            if( prop.GetMethod != null ) Console.WriteLine(
                "  <Get> Name:{0} Attributes:[{1}]",
                prop.GetMethod.Name, prop.GetMethod.Attributes);

            if( prop.SetMethod != null ) Console.WriteLine(
                "  <Set> Name:{0} Attributes:[{1}]",
                prop.SetMethod.Name, prop.SetMethod.Attributes);
        }
    }
}

class Props
{
    public int plGetSet { get; set; }
    public int plGetpvSet { get; private set; }
    public int pvGetplSet { private get; set; }
    public int plGet { get { return 0; } }
    public int plSet { set { } }

    protected int ptGetSet { get; set; }
    internal int inGetSet { get; set; }
    protected internal int ptinGetSet { get; set; }

    private int pvGetSet { get; set; }
    private int pvGet { get { return 0;} }
    private int pvSet { set { } }
}

まとめ

  • get アクセサ/set アクセサのいずれかが public → BindingFlags.Public の対象
  • 上記以外 → BindingFlags.NonPublic の対象

  • get アクセサ無し → CanRead : False → GetMethod : null
  • set アクセサ無し → CanWrite : False → SetMethod : null

0 件のコメント:

コメントを投稿