TL;DR;
const BindingFlags ALL_ACCESS
= BindingFlags.Public
| BindingFlags.NonPublic
| BindingFlags.Instance
| BindingFlags.Static;
static IEnumerable<string> GetMemberNames<T>()
{
var type = typeof(T);
while(type != null)
{
foreach (var member in type.GetMembers(ALL_ACCESS))
{
yield return $"{type.FullName}.{member.Name}";
}
type = type.BaseType;
}
}
結果
System.Int32.CompareTo
System.Int32.CompareTo
System.Int32.Equals
System.Int32.Equals
System.Int32.GetHashCode
System.Int32.ToString
System.Int32.ToString
System.Int32.ToString
System.Int32.ToString
System.Int32.TryFormat
System.Int32.Parse
System.Int32.Parse
System.Int32.Parse
System.Int32.Parse
System.Int32.Parse
System.Int32.TryParse
System.Int32.TryParse
System.Int32.TryParse
System.Int32.TryParse
System.Int32.GetTypeCode
System.Int32.System.IConvertible.ToBoolean
System.Int32.System.IConvertible.ToChar
System.Int32.System.IConvertible.ToSByte
System.Int32.System.IConvertible.ToByte
System.Int32.System.IConvertible.ToInt16
System.Int32.System.IConvertible.ToUInt16
System.Int32.System.IConvertible.ToInt32
System.Int32.System.IConvertible.ToUInt32
System.Int32.System.IConvertible.ToInt64
System.Int32.System.IConvertible.ToUInt64
System.Int32.System.IConvertible.ToSingle
System.Int32.System.IConvertible.ToDouble
System.Int32.System.IConvertible.ToDecimal
System.Int32.System.IConvertible.ToDateTime
System.Int32.System.IConvertible.ToType
System.Int32.GetType
System.Int32.MemberwiseClone
System.Int32.Finalize
System.Int32.m_value
System.Int32.MaxValue
System.Int32.MinValue
System.ValueType.Equals
System.ValueType.CanCompareBits
System.ValueType.FastEqualsCheck
System.ValueType.GetHashCode
System.ValueType.GetHashCodeOfPtr
System.ValueType.ToString
System.ValueType.GetType
System.ValueType.MemberwiseClone
System.ValueType.Finalize
System.ValueType..ctor
System.Object.GetType
System.Object.MemberwiseClone
System.Object.Finalize
System.Object.ToString
System.Object.Equals
System.Object.Equals
System.Object.ReferenceEquals
System.Object.GetHashCode
System.Object..ctor
Type.GetMembers
では継承元のメンバが取れない
リフレクションはあくまでも型に定義されている情報を取ってくるものです。
なので、「その型」に定義されていないメンバはとることができません。
BindingFlags.FlattenHierarchy
を付けることで、publicやprotectedなものはとることができます。
「その型」に定義されている情報というよりは、「その型」にとって見えるメンバといった方が正確でしょうか。
Type.BaseType
について
全ての型はobject
から派生しています。そのため、上記のような処理では最後に来るのはobject
です。
それはint
などの値型も例外ではなく、int
はValueType
(値型)の派生でValueType
はobject
の派生になります。
また、typeof(object).BaseType
はnullになります。
operatorについて
上記の方法だと、組み込み型(intなど)のoperator(四則演算など)が取れません。
これらはコンパイラで特別扱いされるもので、型に定義されているものとは扱いが異なるようです。
実際、int
のメタデータを覗くと、operatorは存在しないことが確認できます。
一方でBigInteger
などでは、op_Divide
などといったメンバ名で取得されます。