簡體   English   中英

如何獲得lambda表達式的值

[英]How to get the value of lambda expression

我對此很困惑。

我正在開發一個HTML擴展方法,該方法接受lambda表達式形式的int值。

我試圖在一個簡單的C#應用​​程序中盡我所能來模擬它。 我無法以所需的lambda表達式的格式調用擴展方法。 這種擴展方法支持某些Telerik控件,而我正在嘗試為我部門中的控件定義一些標准。 (我仍然沒有弄清楚如何將int估價出來)。

我已嘗試對其進行記錄,並盡力命名特定的代碼段!

class Program
{
    static void Main(string[] args)
    {
        var db = new CustomerDatabase<MyCustomers>();
        db.Customers.Add(new MyCustomers { Id = 1, Name = "Gandalf the Grey" });
        db.Customers.Add(new MyCustomers { Id = 2, Name = "Bilbo Baggins" }); 
        //Was watching Fellowship of the Ring while doing this lol

        //This foreach is similar to the foreach that would be 
        //in my MVC view where db.Customers is really my ViewModel
        foreach (var item in db.Customers)
        {
            //This is where my trouble begins... :(
            Helpers.WriteIdToConsole(item, item.Id);
            Helpers.WriteIdToConsole(item => );
        }
    }

    /// <summary>
    /// CLASS #1
    /// Serves as a holding container for records
    /// </summary>
    /// <typeparam name="TModel"></typeparam>
    public class CustomerDatabase<TModel>
        where TModel : class
    {
        public List<TModel> Customers { get;set; }
    }

    /// <summary>
    /// CLASS #2
    /// Simple 'model' class in an MVC View
    /// </summary>
    public class MyCustomers
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    /// <summary>
    /// CLASS #3
    /// Replicates a custom HtmlExtension class I'm developing
    /// </summary>
    public static class Helpers
    {
        /// <summary>
        /// Method #A
        /// One of the methods I'm working on
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="expression"></param>
        public static void WriteIdToConsole<T>(Expression<Func<T, int>> expression)
            where T : class 
        {
            var id = 999;
            Console.WriteLine($"Id: {id}");
        }
    }
}

更新#1

這是我在“剃刀視圖”中可以訪問的內容。 cols.NavigationButton方法是我嘗試構建的擴展方法。 如果與下面的Kirill Shlenskiy的建議答案保持一致,我必須創建Event類型或TObj類型的新實例。

@model List<Event>

@(Html.Kendo().Grid<Event>()
      .Name("pagingGrid")
      .Columns(cols =>
      {
          cols.NavigationButton("Edit", "Edit", "Event",new Event(), p => p.Id);
          cols.Bound(p => p.Name);
      })
      .StandardPagingGrid("Event", "Administration")
)

您需要將Expression傳遞給方法,還需要顯式指定type參數。

您可以使用/調用該方法( WriteIdToConsole ),如下所示

foreach (var item in db.Customers)
{
    Helpers.WriteIdToConsole<MyCustomers>(myCustomer => myCustomer.Id);
}

是完整的代碼審查的點網小提琴。

在你的問題,你說你還是搞清楚“如何獲得int值了”,所以我會假設你一個更通用的實現,可以給你所訪問的成員及其值的名稱后是。 這是您的摘錄:

public static void WriteToConsole<TObj, TMember>(TObj obj, Expression<Func<TObj, TMember>> expression)
{
    MemberExpression memberExpr = (MemberExpression)expression.Body;
    string memberName = memberExpr.Member.Name;
    Func<TObj, TMember> compiledDelegate = expression.Compile();
    TMember value = compiledDelegate(obj);

    Console.WriteLine($"{memberName}: {value}");
}

用法:

var dummy = new Dummy { ID = 123 };

WriteToConsole(dummy, d => d.ID); // Outputs "ID: 123"

我已經刪除了通用引用類型約束( where T : class ),因為這也可以在值類型上正常工作。

需要注意的關鍵是,要提取值,您不僅需要能夠執行此操作的表達式,還需要一個實例以傳遞給從該表達式編譯的委托(因此,使用第一個Helpers.WriteIdToConsole正確的軌道上)調用您的代碼-您只需要將其到達終點即可。

編輯

如果只關心從表達式中提取基本成員信息,則可以使用稍微不同的方法:

public static MemberInfo Member<T>(Expression<Func<T, object>> expr)
{
    // This is a tricky case because of the "object" return type.
    // Providing an expression which has a value return type will
    // result in a UnaryExpression body, whereas an expression which
    // has a reference return type will have a MemberExpression Body.
    UnaryExpression unaryExpr = expr.Body as UnaryExpression;
    MemberExpression memberExpr = (MemberExpression)(unaryExpr == null ? expr.Body : unaryExpr.Operand);

    return memberExpr.Member;
}

基本用法:

MemberInfo id = Member<MyCustomers>(item => item.Id);

Console.WriteLine(id.Name); // Outputs "Id"

插入方式:

public static void NavigationButton<T>(string ..., string ..., string ..., Expression<Func<T, object>> expression)
{
    MemberInfo member = Member(expression);

    // Do something with member, cast to PropertyInfo if needed etc.
}

...

NavigationButton<MyCustomers>("Edit", "Edit", "Event", p => p.Id);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM