2014-04-03 30 views
2

是什麼類型化和非類型化的代表

var propertyResolver = Expression.Lambda<Func<Person, object>>(expr, arg).Compile(); 
string name = (string)propertyResolver(p); 

var propertyResolver = Expression.Lambda(expr, arg).Compile(); 
string name = (string)propertyResolver(p); 

之間的差別在第二種情況下有某種「非類型化」的代表。

那是什麼?

編輯:

ParameterExpression arg = Expression.Parameter(p.GetType(), "x"); 
Expression expr = Expression.Property(arg, "Name"); 
+1

這是什麼類型的'expr'? –

+0

特別是,第二個版本是爲你編譯的嗎? –

+0

都編譯。 ParameterExpression arg = Expression.Parameter(p.GetType(),「x」); Expression expr = Expression.Property(arg,「Name」); –

回答

1

第一個代碼是Expression.Lambda<TDelegate>的呼叫時,它返回一個Expression<TDelegate>,其具有Compile()方法返回TDelegate。所以propertyResolver在你的情況下的類型是Func<Person, Object>

第二個代碼是對非通用Expression.Lambda方法的調用,該方法返回LambdaExpression。這有一個Compile()方法,只是返回Delegate。所以propertyResolver在你的情況下的類型是Delegate - 這就是爲什麼propertyResolver(p)不會編譯。

+0

好吧,到目前爲止,我已經明白了你的觀點,但我可以在第二個對話框中調用DynamicInvoke?關鍵是,無論我在代碼中犯了錯誤,我都可以調用它們。讓我們打電話給我的代碼僞代碼。我很抱歉在我的代碼中犯了錯誤。我的問題仍然是那些Func 代表與普通簡單System.Delegate之間的區別。兩者都可以被調用。爲什麼Func更快?是否因爲某種方式func知道類型和那些簡單的普通代表沒有? –

+1

@devhedgehog:是的,你可以,如果你想。不同之處在於''Func <,>'示例中有一個具體的,編譯時間已知的類型。這就像使用'string x =「foo」的區別。 int y = x.Length;'和'dynamic x =「foo」; int y = x.Length;'。請注意,一般情況下使用普通的'Delegate'非常罕見。 –

+0

好的。我明白了。謝謝。順便說一句,我怎麼能這樣做:Expression.Lambda >(..)? –