Поля на лету от статического отражения? - PullRequest
2 голосов
/ 17 апреля 2009

Я изучал статическое отражение с помощью выражений LINQ - очень круто!

Одна мысль, которая у меня возникла - возможно ли, чтобы один класс «генерировал» поля в одном классе на основе статического отражения, сделанного в другом классе? Я имею в виду именно образец Строителя, который видел здесь много раз. Я хотел бы сделать регистрацию свойств в стиле беглого nhibernate, которая «генерирует» поля в компоновщике, которые соответствуют классу, который я хочу построить. Что-то вроде этого:

public class Color
{
    private Color()
    {
    }
    public string Name { get; private set; }

    public class Builder : BuilderBase<Color>
    {
        public Builder()
        {
            Property(x => x.Name);
        }
        public Build()
        {
            return built_up_color;
        }
    }
}

и синтаксис конструктора поддержки, например:

Color c = new Color.Builder() { Name = "Red" }.Build();

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

public class Color
{
    private Color()
    {
    }
    public string Name { get; private set; }

    public class Builder
    {
        private Color _color = new Color();
        public string Name
        {
            get { return _color.Name; }
            set { _color.Name = value; }
        }

        public Build()
        {
            return _color;
        }
    }
}

, который, безусловно, работает И перечисляет свойства столько же раз, но кажется более смелым и менее гибким. Похоже, я должен быть в состоянии сделать что-то анонимно-типа-у здесь?

Ответы [ 3 ]

1 голос
/ 24 апреля 2009

Стоит отметить, что иметь класс с именем Color, конфликтующий с System.Drawing.Color, вероятно, плохая идея.

очень может привести к путанице в других (еще хуже, System.Drawring.Color имеет семантику значений, тогда как у вашего класса есть семантика ссылок, которая может привести к дальнейшей путанице)

Я бы отметил, что вы действительно хотите Именованные необязательные аргументы . Я бы предположил, что теперь ввод громоздких классов Builder будет более трудоемким, и переход к ним станет более болезненным, когда вы доберетесь до c # 4.0. Вместо этого сделайте конструкторы, которые требуются (или, если необходимо, чтобы избежать коллизий сигнатур типов, статические фабричные методы в классе)

0 голосов
/ 17 февраля 2012

меньше кода для записи, но с использованием отражения для установки значений.

Хитрость заключается в использовании инициализаторов коллекции. это безопасно.

public class Color
{
    private Color()
    {
    }
    public string Name { get; private set; }
    public int Prop2 { get; private set; }

    public class Builder : Builder<Color>
    {
        public Builder()
        {
            // possible
            _instance.Name = "SomeDefaultValue";
        }
    }
}

class Builder<T> : IEnumerable<string>
{
    protected T _instance = Activator.CreateInstance(typeof(T));

    public void Add<TProperty>(Expression<Func<T, TProperty>> prop, TProperty value)
    {
        StaticReflection.GetPropertyInfo(prop).SetValue(_instance, value, null);
    }

    public static implicit operator T(Builder<T> builder)
    {
        return builder.Build();
    }

    public T Build()
    {
        return _instance;
    }

    IEnumerator<string> IEnumerable<string>.GetEnumerator()
    {
        // e.g. return iterator over the property names
        throw new NotImplementedException();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return ((IEnumerable<string>)this).GetEnumerator();
    }
}

и синтаксис вызова

var color = new Color.Builder
{
    { x => x.Name, "foo" },
    { x => x.Prop2, 5 }
}.Build();

// or

var color = new Builder<Color>
{
    { x => x.Name, "foo" },
    { x => x.Prop2, 5 }
}.Build();

// or

Color color = new Builder<Color>
{
    { x => x.Name, "foo" },
    { x => x.Prop2, 5 }
};
0 голосов
/ 17 апреля 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...