2011-05-03 52 views
7

我想「包裝」屬於特定類型的特定屬性的getter函數。 我有一個抽象類,等被定義如下:Lambda表達式:將參數強制轉換爲基類型

public abstract class MyAbstractClass<T> where T : MyType 
{ 
    // ... 
} 

好吧,假設我有一個具體的類像下面的一個:

public abstract class MyConcreteClass : MyAbstractClass<MyConcreteType> 
{ 
    // ... 
} 

而現在,輔助方法應該返回一個包裝爲getter方法:

private Func<MyAbstractClass<T>, Object> GetPropertyGetter(PropertyInfo property) 
{ 
    var instanceType = Expression.Parameter(property.DeclaringType, "i"); 

    // Taking getter's "body". 
    var getterBody = Expression.Property(instanceType, property); 

    // Cast to a generic Object. 
    var body = Expression.TypeAs(getterBody, typeof(Object)); 

    // Build the expression. 
    var exp = Expression.Lambda<Func<MyAbstractClass<T>, Object>>(body, instanceType); 
    return exp.Compile(); 
} 

就像預期的,我得到以下異常:

類型'MyConcreteClass'的參數表達式不能用於 類型爲'MyAbstractClass <MyConcreteType>'的委託參數。

有沒有辦法「強制」這種鑄造?提前致謝。

+1

這個問題非常混亂。爲什麼有一個叫做「MyConcreteClass」的抽象類。 「具體」與「抽象」是相反的;這是故意混淆的嗎?兩個「T」是相同的,還是兩個不同的類中有兩個不同的T的聲明?爲什麼你首先想要做這件奇怪的事情? – 2011-05-03 07:08:12

回答

11

如果我正確理解你的問題,你想創建這樣一個lambda表達式:

Func<MyAbstractClass<T>, Object> f = i => ((MyConcreteClass)i).SomeProperty; 

除了要提供財產SomeProperty作爲參數。那麼,如果你想以編程方式構建該表達式,則必須完全相同:具有表達式參數i(類型MyAbstractClass<T>),將其轉換爲MyConcreteClass,然後訪問屬性SomeProperty

public Func<MyAbstractClass<T>, Object> GetPropertyGetter(PropertyInfo property) 
{ 
    var parameter = Expression.Parameter(typeof(MyAbstractClass<T>), "i"); 

    var cast = Expression.TypeAs(parameter, property.DeclaringType); 

    var getterBody = Expression.Property(cast, property); 

    var exp = Expression.Lambda<Func<MyAbstractClass<T>, Object>>(
     getterBody, parameter); 

    return exp.Compile(); 
} 

說了這麼多,我也絕對不知道你爲什麼會想這樣做,所以你最好是真的相信這是你想要做什麼,有沒有做你的什麼更好的方法實際上想要做的。

+0

+1我正在尋找'Expression.TypeAs'的樣本。感謝分享。 – digaomatias 2013-12-30 14:47:52

0

不應該從通用類型構建實例類型嗎?

var genericType = typeof(MyAbstractClass<>).MakeGenericType(property.DeclaringType); 
var instanceType = Expression.Parameter(genericType , "i"); 
相關問題