Вопрос

Я работаю над методом, который принимает дерево выражений в качестве параметра вместе с типом (или экземпляром) класса.

Основная идея заключается в том, что этот метод добавит определенные элементы в коллекцию, которые будут использоваться для проверки.

public interface ITestInterface
{
    //Specify stuff here.
}

private static void DoSomething<T>(Expression<Func<T, object>> expression, params IMyInterface[] rule)
{
    // Stuff is done here.
}

Метод вызывается следующим образом:

class TestClass
{
    public int MyProperty { get; set; }
}

class OtherTestClass  : ITestInterface
{
    // Blah Blah Blah.
}

static void Main(string[] args)
{
    DoSomething<TestClass>(t => t.MyProperty, 
        new OtherTestClass());
}

Я делаю это таким образом, потому что мне бы хотелось, чтобы имена свойств, которые передаются, были строго типизированными.

Пара вещей, с которыми я борюсь..

  1. В рамках doSomething я хотел бы получить PropertyInfo введите (из переданного тела) T и добавьте его в коллекцию вместе с правилом[].В настоящее время я подумываю об использовании expression.Body и удалении [propertyname] из "Convert.([propertyname])" и использовании отражения, чтобы получить то, что мне нужно.Это кажется громоздким и неправильным.Есть ли способ получше?
  2. Это какой-то конкретный шаблон, который я использую?
  3. Наконец, приветствуются любые предложения или разъяснения относительно моего непонимания того, что я делаю, и / или ресурсы или хорошая информация о деревьях выражений C #.

Спасибо!

Йен

Редактировать:

Пример того, что expression.Body.ToString() возвращает внутри метода doSomething строку, содержащую "Convert(т.MyProperty)", если она вызвана из примера выше.

Мне действительно нужно, чтобы он был строго типизирован, поэтому он не будет компилироваться, если я изменю имя свойства.

Спасибо за предложения!

Это было полезно?

Решение

Сбор объектов PropertyInfo из выражения.Тело похоже на мое решение перейдем к другому вопросу.

Другие советы

Я в значительной степени полагаюсь на деревья выражений, чтобы перенести многое из того, что я хочу сделать с моим текущим приложением, во время компиляции, т.е.статическая проверка типов.

Я просматриваю деревья выражений, чтобы перевести их во что-то другое, что "имеет смысл".

Одна вещь, которую я в конечном итоге часто делаю, - это то, что вместо URL-адресов я полагаюсь на подход, подобный MVC, где я объявляю лямбда-функции и транслирую их...интерпретируя, компилятор сгенерировал дерево выражений в URL-адрес.Когда вызывается этот URL-адрес, я делаю обратное.Таким образом, у меня есть то, что я называю проверкой неработающих ссылок во время компиляции, и это также отлично работает при рефакторинге и перегрузках.Я думаю, что это здорово - подумать об использовании деревьев выражений таким образом.

Возможно, вы захотите проверить шаблон visitor, с ним сложно начать, потому что вначале он не имеет особого смысла, но он связывает все воедино, и это очень формальный способ решения проблемы проверки типов при построении компилятора.Вы могли бы сделать то же самое, но вместо проверки типа выдавайте все, что вам нужно.

То, над чем я сейчас ломаю голову, - это возможность создать простой фреймворк для перевода (или, на самом деле, я должен сказать, интерпретировать) выражения tress и emit JavaScript.Идея заключается в том, что сгенерированные компилятором деревья выражений будут транслироваться в допустимый JavaScript, который взаимодействует с некоторой объектной моделью.

Что в этом интересного, так это то, что компилятор всегда может сказать мне, когда я что-то делаю не так, и уверен, что конечным результатом будет всего лишь набор строк, но важной частью является то, как эти строки были созданы.Они прошли некоторую проверку, и это кое-что значит.

Как только вы добьетесь этого, вы мало что сможете сделать с деревьями выражений.

Во время работы с системой.Размышления.Я обнаружил, что использую деревья выражений для создания облегченного фреймворка для динамической компиляции, который во время компиляции мог в принципе сказать, будут ли компилироваться и мои динамически созданные сборки, и это без проблем работало с отражением и статической проверкой типов.Мы продвигались все дальше и дальше и в итоге получили нечто, что в итоге сэкономило много времени и оказалось очень гибким и надежным.

Так что мне нравятся подобные вещи, и в этом суть метапрограммирования - писать программы в ваших программах, которые выполняют программы.Я говорю, продолжай в том же духе!

Я ценю то, что вы пытаетесь сделать с здешней собственностью.Я столкнулся с этой головоломкой.Писать всегда кажется странным:

DoSomething("MyProperty", new OtherClass());

Если свойство когда-либо изменит имя или текст будет набран с ошибкой при вызове, то возникнет проблема.Что я пришел, чтобы узнать, так это то, что с этим вам, вероятно, придется иметь дело с помощью тестирования.В частности, модульное тестирование.Я бы написал модульные тесты, чтобы убедиться, что вызовы "doSomething" работают корректно.

Другая вещь, которую вы могли бы попробовать, - это украсить ваши свойства атрибутами, а затем отразить их в вашем классе, когда он создается для поиска свойств с этим атрибутом, и загрузить правила.

[DoSomething(typeof(OtherClass), typeof(OtherClass2))]
public int MyProperty
{
  get;
  set;
}

В этом случае конструктор (возможно, в базовом классе?) будет динамически создавать объект OtherClass и объект OtherClass2 и загружать их в коллекцию вместе с именем свойства.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top