簡體   English   中英

C# 使用表達式從 object 獲取值

[英]C# Use Expression to get value from an object

object 雲是任何 class,我不想使用反射。 這是我的代碼:

class Dog
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }

        static void test()
        {
            object d = new Dog
            {
                Id = 21,
                Name = "adsf"
            };
            genericeTest(d);
        }

        static void genericeTest<T>(T t)
        {
            var type = t.GetType();
            var arg = Expression.Parameter(type, "x");
            var expr = Expression.Property(arg, "Id");
            var compiled = Expression.Lambda<Func<T, int>>(expr, arg).Compile();
            var value = compiled.Invoke(t);
        }

但有異常System.ArgumentException: ParameterExpression of type 'ExpressionDemo.Program+Dog' cannot be used for delegate parameter of type 'System.Object' var compiled = Expression.Lambda<Func<T, int>>(expr, arg).Compile();

如果我這樣寫

   var compiled = Expression.Lambda<Func<Dog, int>>(expr, arg).Compile();
   var value = compiled.Invoke(t as Dog);

它運作良好。 我可以修一下嗎,謝謝。

問題是您的Tobject ,因為d的編譯時類型為object ,但t.GetType()Dog ,因為t的運行時類型是Dog

因此,您有一個接受Dog的表達式,但您試圖將object類型的變量傳遞給它——您缺少將object變成Dog的演員表。

換句話說,您正在編寫的內容大致相當於:

public int GeneratedMethod(object o)
{
    Dog d = o; // <-- This line will cause a compile-time error, of course
    return d.Id;
}

問題是,您希望生成的方法是什么樣的? 它應該看起來像這樣嗎?

public int GeneratedMethod(object o)
{
    Dog d = (Dog)o;
    return d.Id;
}

如果是這樣,您需要將演員表從object插入到Dog 這樣做的方法是使用Expression.Convert

var type = t.GetType();
var arg = Expression.Parameter(typeof(T), "x");
var expr = Expression.Property(Expression.Convert(arg, type), "Id");
var compiled = Expression.Lambda<Func<T, int>>(expr, arg).Compile();

在這里,我們聲明了一個 lambda ,它接受一個T ,然后將其轉換為Dog

暫無
暫無

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

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