Debug.Print(GetDisplayName(Function() ClassA.Alpha)) 'Shared プロパティ Debug.Print(GetDisplayName(Sub() Me.SubProc())) 'インスタンス Sub メソッド Debug.Print(GetDisplayName(Function() Me.FuncProc())) 'インスタンス Function メソッド Dim cOleDb As New System.Data.OleDb.OleDbConnectionStringBuilder() Debug.Print(GetDisplayName(Function() cOleDb.DataSource)) 'インスタンス プロパティ Debug.Print(GetDisplayName(Function() cOleDb.FileName)) Debug.Print(GetDisplayName(Function() cOleDb.OleDbServices)) Debug.Print(GetDisplayName(Function() cOleDb.PersistSecurityInfo))
Public Shared Function GetDisplayName(Of T)(proc As Expression(Of T)) As String If proc Is Nothing OrElse TypeOf proc.Body Is ConstantExpression Then Return Nothing End If Dim m = TryCast(proc.Body, MemberExpression) 'フィールドやプロパティ Dim c = TryCast(proc.Body, MethodCallExpression) 'メソッド Dim atr As DisplayNameAttribute = Nothing If m IsNot Nothing Then atr = m.Member.GetCustomAttributes(Of DisplayNameAttribute)().FirstOrDefault() If atr Is Nothing AndAlso m.Member.MemberType = MemberTypes.Property Then 'プロパティには付与されていなかったが、getter や setter には付与されている可能性がある Dim getter = TryCast(m.Member, PropertyInfo)?.GetGetMethod(False) 'Dim setter = TryCast(m.Member, PropertyInfo)?.GetSetMethod(False) If getter IsNot Nothing Then atr = getter.GetCustomAttributes(Of DisplayNameAttribute)().FirstOrDefault() End If End If ElseIf c IsNot Nothing Then atr = c.Method.GetCustomAttributes(Of DisplayNameAttribute)().FirstOrDefault() If atr Is Nothing AndAlso c.Method.IsSpecialName AndAlso c.Method.Name.StartsWith("get_") Then '引数付きプロパティの getter が渡されたら、親プロパティの属性もさぐる Dim propName = c.Method.Name.Substring(4) Dim full = BindingFlags.Instance Or BindingFlags.Static Or BindingFlags.Public Or BindingFlags.NonPublic Dim prop = c.Method.ReflectedType.GetProperties(full) _ .Where(Function(p) p.Name = propName AndAlso p.GetGetMethod() Is c.Method) _ .FirstOrDefault() atr = prop?.GetCustomAttributes(Of DisplayNameAttribute)()?.FirstOrDefault() End If End If Return atr?.DisplayName End Function