Как привести экземпляр Enumerable <T>.Where (Predicate) к IEnumerable <T>? - PullRequest
1 голос
/ 18 июля 2011

Я пишу генератор кода на C #. В некоторых местах я должен привести тип возвращаемого значения метода Linq, например WhereSelectListIterator, к типу IEnumerable. Как я могу это сделать?

Сценарий: У меня есть экземпляр списка с именем 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 (), ...). Что я могу сделать?

Ответы [ 2 ]

1 голос
/ 15 ноября 2011

Вы можете вызывать методы расширения для dynamic объектов, таких как:

dynamic result = Enumerable.Where(collection, (Func<dynamic, bool>)delegate(dynamic item)
                                              {
                                                   return item.Id == id;
                                               });
1 голос
/ 18 июля 2011

В ответ на вопрос, который вы задаете в заголовке, результат Enumerable<T>.Where(Predicate) реализует IEnumerable<T>, просто разыграйте его, не нужно делать что-то причудливое.См. Здесь: Метод Enumerable..Where (TSource) (IEnumerable (TSource), Func (TSource, Boolean))

В остальном, почему вы пытаетесь сгенерировать код C #?Если вы пытаетесь оценить фрагмент кода, который был введен во время выполнения, почему бы не использовать компилятор C # для его компиляции?Я гуглил для «программной компиляции C #», и первым результатом стала страница поддержки Microsoft: Как программно скомпилировать код с использованием компилятора C #

...