從5分鐘前我問過這個問題 ,很明顯以下代碼會引發異常,說明這一點
未處理的異常:System.InvalidOperationException:沒有為類型'System.Nullable`1 [System.Int32]'和'System.Int32'定義二進制運算符Equal。
碼
public static void GetResultCollection<T>() {
AccrualTrackingEntities db = new AccrualTrackingEntities();
var result = db.CreateQuery<T>(String.Format("[{0}]", typeof(T).Name + "s"));
int? ItemTypeValue = 1;
var param = Expression.Parameter(typeof(T));
var lambda = Expression.Lambda<Func<T, bool>>(
Expression.Equal(
Expression.Property(param, "ProcInstId"),
Expression.Constant(ItemTypeValue)),
param);
var list = result.Where(lambda).ToList();
}
但是,此代碼與Expression.Constant
中明確列出的類型確實有效
class Program {
public static void GetResultCollection<T>() {
AccrualTrackingEntities db = new AccrualTrackingEntities();
var result = db.CreateQuery<T>(String.Format("[{0}]", typeof(T).Name + "s"));
int? ItemTypeValue = 1;
var param = Expression.Parameter(typeof(T));
var lambda = Expression.Lambda<Func<T, bool>>(
Expression.Equal(
Expression.Property(param, "ProcInstId"),
Expression.Constant(ItemTypeValue, typeof(int?))),
param);
var list = result.Where(lambda).ToList();
}
問題是, 為什麼 Expression.Constant
無法從int?
隱式轉換int?
到... int?
表達式樹在較低級別上工作到正常的源代碼 - 您可以將它們視為在編譯器輸出級別而不是輸入級別工作。那麼雖然從int
到int?
的隱式轉換int?
在C#中,只要編譯器將其用於普通方法,就必須在IL中表示轉換...因此它也必須存在於表達式樹表示中。
說到這一點,你的例子有點不清楚,因為你試圖使用int
(即ItemTypeValue.Value
)作為int?
的值int?
常量,我們不知道ItemType
屬性的類型是什麼。
您期望工作的一個簡短而完整的例子真的會有所幫助。
編輯:好的,我想我現在和你在一起。問題是,如果你使用
int? foo = 1;
Expression.Constant(foo);
然後調用Expression.Constant(object)
了foo
值的Expression.Constant(object)
。那時, Expression.Constant
不能告訴它原來是一個int?
,因為它現在是一個盒裝的int
。這就是.NET拳擊的工作方式:
int? foo = 1;
object o = foo;
Console.WriteLine(o.GetType()); // Prints System.Int32
Expression.Constant
重載從它給出的值確定Expression.Constant
的整體類型 - 所以它創建一個int
表達式,而你真的想要一個int?
表達。
為了正確維護類型信息,您必須使用允許您指定類型的重載:
int? foo = 1;
Expression.Constant(foo, typeof(int?));
你的問題仍然不完全清楚哪些代碼有效,哪些代碼無效,但希望這有助於......