2017-10-21 4 views
1

を指し、 -name(SomeProperty)この小さなスニペットにより、(インターネットからの長い時間のエゴを得た):t => (t.Some1 As Object)は、参照するプロパティではありません。式 `トン=>(オブジェクトとしてt.SomeProperty)は`私はいくつかのコードでこの式を作成している方法ではなく、プロパティ

public static PropertyInfo GetPropertyInfo<TSource, TProperty> 
     (TSource source, Expression<Func<TSource, TProperty>> propertyLambda) { 
     var type = typeof(TSource); 

     var member = propertyLambda.Body as MemberExpression; 
     if (member == null) 
      throw new ArgumentException($"Expression '{propertyLambda}' refers to a method, not a property."); 

     var propInfo = member.Member as PropertyInfo; 
     if (propInfo == null) 
      throw new ArgumentException($"Expression '{propertyLambda}' refers to a field, not a property."); 

     if (type != propInfo.ReflectedType && !type.IsSubclassOf(propInfo.ReflectedType)) 
      throw new ArgumentException($"Expresion '{propertyLambda}' refers to a property that is not from type {type}."); 

     return propInfo; 
    } 

しかし、あなたが知っているように、propertyLambda.Body as MemberExpressionはこれを引き起こし、常にnullです。この場合、プロパティ名を取得する方法はありますか?

答えて

4

C#asオペレータがExpression.TypeAsに変換し、C#のキャスト演算子がExpression.ConvertまたはExpression.ConvertCheckedのいずれかに変換します。ご覧のとおり、すべてがUnaryExpressionタイプなので、Operandプロパティを使用してオペランド式を抽出できます。また、複数のキャストをサポートするためにループ内で行うこともできます。行動にそれを置く

var operand = propertyLambda.Body; 
while (operand.NodeType == ExpressionType.TypeAs || operand.NodeType == ExpressionType.Convert || operand.NodeType == ExpressionType.ConvertChecked) 
    operand = ((UnaryExpression)operand).Operand; 
var member = operand as MemberExpression; 

var member = propertyLambda.Body as MemberExpression; 

を交換

0

私はこれをお勧めします:

PropertyInfo info = t.GetType().GetProperty("SomeProperty", 
    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); 
// Use these binding flags to get a member of any visibility. 

それは与えられた名前のプロパティのPropertyInfoを返します。

明示的に名前を処理しない場合は、nameof(t.SomeProperty)を使用してください。

特定のタイプのすべてのプロパティを取得するには、.GetPropertiesメソッドが便利です。

1

あなたの場合、キャストである単項式のオペランドを調べる必要があります。

((propertyLamdba.Body as UnaryExpression).Operand as MemberExpression).Member 

よりプログラム的に安全にするには、プロパティLambaを確認する必要があります。以下のような 何か:

if (propertyLamdba.Body.NodeType == ExpressionType.TypeAs) 
    member = ((propertyLamdba.Body as UnaryExpression).Operand as MemberExpression).Member 
関連する問題