2011-07-18 53 views
1

我正在寫一個C#代碼生成器。在某些地方,我必須將返回類型的Linq方法(如WhereSelectListIterator)轉換爲IEnumerable類型。我該怎麼做?如何投射Enumerable的實例<T>。Where(Predicate)to IEnumerable <T>?

場景: 我有一個List實例名爲aList。我在文本框中寫入以下表達式:

aList.Where(item => item.StartsWith("s")).Select(item => item.ToUpper()).ToList().Count 

我需要編寫一個應用程序來評估我的表達式。我知道我必須編寫一個C#代碼生成器來評估我的表達。 如果我直接評估上述表達式,它是有效的。但是假設我有以下情形:

public Interface IInterface 
{ 
} 
public class MyClass:IInterface 
{ 
    public int Id = 10; 
    public IInterface GetInstance() 
    { 
     return new MyClass(); 
    } 
} 

public class Program 
{ 
    public static void Main() 
    { 
     var myClass = new MyClass(); 
     myClass.GetInstance().Id.ToString(); 
    } 
} 

當我使用Id屬性調用getInstance()方法後,它會導致CLR拋出一個異常,因爲IInterface還沒有ID屬性。我需要將返回類型的GetInstance()強制轉換爲MyClass,然後使用Id屬性。 我怎樣才能做到這一點動態投射。 一個解決方案是使用動態對象。

var myClass = new MyClass(); 
dynamic x = myClass.GetInstance(); 
dynamic y = myClass.Id; 
y.ToString(); 

但動態對象有擴展方法的問題(例如:Where(),Take(),...)。我能做什麼?

+0

順便說一句,'在哪裏(謂語).Count之間()'應該被替換爲只是'Count(謂詞)' – abatishchev

+0

我知道Count(),但我想aList.Where(謂詞).Count Count屬於列表評估沒有錯誤。我在這種情況下施用什麼? –

+0

當調用方法是非擴展時,動態對象很有用。但在擴展方法中,我必須在這種情況下做什麼? –

回答

1

在回答你在標題中提出的問題時,Enumerable<T>.Where(Predicate)的執行結果爲IEnumerable<T>,只是施放它,不需要做任何幻想。看到這裏:Enumerable..Where(TSource) Method (IEnumerable(TSource), Func(TSource, Boolean))

至於其他,你爲什麼要生成C#代碼?如果您試圖評估在運行時輸入的代碼片段,爲何不使用C#編譯器進行編譯?我用Google搜索「C#編程彙編」,和第一個結果是這個微軟支持頁面:How to programmatically compile code using C# compiler

+0

我認爲你不明白我的要求。爲了解決問題,我必須首先按點分割我的表達式,因爲正如我在上面的場景中提到的那樣。所以當我有IEnumerator 。Where(謂詞)我怎麼能理解T確切類型(字符串或int或...)。 in myClass.GetInstance()。Id.ToString();我怎麼能猜測適當的類型鑄造--->(myClass.GetInstance()as MyClass).Id; 我的問題是找到MyClass類型來動態地進行適當的投射。 –

+0

但他是正確的返回Where()是一個Queryable 正好實現IEnumerable 以及。無需投射。 – ivowiblo

+0

大衛是對的。類型參數:T由編譯器推斷。 –

1

您可以撥打dynamic對象這樣的擴展方法:

dynamic result = Enumerable.Where(collection, (Func<dynamic, bool>)delegate(dynamic item) 
               { 
                return item.Id == id; 
               }); 
相關問題