6

私はこのような静的メソッドを持っています:

    public static string MyMethod(Func<Student, object> func)
    {            
        return ??? ;
    }

そして私はそれを次のように使います。

    var s1 = MyMethod(student => student.ID); // Return "ID" ???
    var s2 = MyMethod(student => student.Age); // Return "Age" ???
    var s3 = MyMethod(student => student.Name); // Return "Name" ???

次のような結果を返すwriteメソッドはどうやって?

  • s1:「ID」
  • s2:「年齢」
  • s3:「名前」

*=>の後の各プロパティの名前を文字列として返します。


  • この署名ではできません - それは次のようなものでなければなりませんExpression<Func<Student, object>>。 - Jon

3 답변


1

あなたのメソッドのシグネチャを変更することができます から

  public static string MyMethod(Func<Student, object> func)

に変更

  public static string MyMethod(Expression<Func<Student, object>> func) {
     return GetMemeberName(func)
  } 

  public static string GetMemberName(Expression expression)
    {            
        if (expression is LambdaExpression)
        {
            var lambdaExpression = (LambdaExpression)expression;
            return GetMemberName(lambdaExpression.Body);                              
        }

        if (expression is MemberExpression)
        {
            var memberExpression = (MemberExpression)expression;
            if (memberExpression.Expression.NodeType == ExpressionType.MemberAccess)
            {
                return GetMemberName(memberExpression.Expression)+ "."+ memberExpression.Member.Name;
            }
            return memberExpression.Member.Name;
        }

        if (expression is UnaryExpression)
        {
            var unaryExpression = (UnaryExpression)expression;
           if (unaryExpression.NodeType != ExpressionType.Convert)
                throw new Exception(string.Format(
                    "Cannot interpret member from {0}",
                    expression));
            return GetMemberName(unaryExpression.Operand);
        }
        throw new Exception(string.Format("Could not determine member from {0}",expression));
    }  


  • これは良いことですが、あなたはそれを機能させる方法を彼に伝えなければなりません。 OPはFunc<>ではないExpression。 - Gabe
  • 基本的にこれは便利ですが、述べられている質問に答えるには程遠いコードの束です。それが本当の答えになれば私はこれを支持するでしょう。 - Jon
  • また、型のパラメータでExpressionラムダを使って呼び出すことはできません。 - Servy
  • @Gabeはいくつかの説明を追加しました - vittore
  • @Jonが詳細を追加しました - vittore

0

署名を検査できるようにするには、署名にfuncではなく式treeを含める必要があります。幸いなことに、コンパイラーはラムダから式を作成するので、呼び出しは変わりません。

このバージョンはおそらく最短で、再帰は含まれませんが、単純なプロパティアクセスのラムダに対してのみ機能します。

public static string MyFunc( Expression<Func<Student, object>> Property )
{
     if ( Property != null && Property.Body != null )
         if ( Property.Body.NodeType == ExpressionType.MemberAccess )
         {
             MemberExpression memberExpression = 
                (MemberExpression)Property.Body;

             if ( !string.IsNullOrEmpty( memberExpression.Member.Name ) )
                 return memberExpression.Member.Name;

         }

     return string.Empty;
 }


0

からもう一つのSOの質問、これはあなたが探しているものかもしれません:

public static string GetPropertyName<T>(Expression<Func<T>> propertyExpression)
{
    return (propertyExpression.Body as MemberExpression).Member.Name;
}

それを使うためには、次のように書きます。

var propertyName = GetPropertyName(
    () => myObject.AProperty); // returns "AProperty"

リンクされた質問


関連する質問

最近の質問