Создание объекта, передающего лямбда-выражение в конструктор - PullRequest
3 голосов
/ 10 июня 2009

У меня есть объект с рядом свойств.

Я хочу иметь возможность назначать некоторые из этих свойств при вызове конструктора.

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

Так что я подумал, не было бы неплохо, если бы я мог сказать ..

MyObject x = new MyObject(o => o.Property1 = "ABC", o.PropertyN = xx, ...);

Проблема в том, что я слишком слаб, чтобы понять, как сделать это.

Знаете ли вы?

Ответы [ 4 ]

8 голосов
/ 10 июня 2009

C # 3 позволяет вам делать это с помощью инициализатора объекта синтаксиса.

Вот пример:

using System;

class Program
{
    static void Main()
    {
        Foo foo = new Foo { Bar = "bar" };
    }
}

class Foo
{
    public String Bar { get; set; }
}

Способ, которым это работает, заключается в том, что компилятор создает экземпляр класса с именем, сгенерированным компилятором (например, <>g__initLocal0). Затем компилятор берет каждое свойство, которое вы инициализируете, и задает значение свойства.

По сути, компилятор переводит метод Main, описанный выше, во что-то вроде этого:

static void Main()
{
    // Create an instance of "Foo".
    Foo <>g__initLocal0 = new Foo();
    // Set the property.
    <>g__initLocal0.Bar = "bar";
    // Now create my "Foo" instance and set it
    // equal to the compiler's instance which 
    // has the property set.
    Foo foo = <>g__initLocal0;
}
4 голосов
/ 26 марта 2012

Синтаксис инициализатора объекта является самым простым в использовании и не требует дополнительного кода для конструктора.

Однако, если вам нужно сделать что-то более сложное, например, вызвать методы, у вас может быть конструктор, который принимает параметр Action для выполнения заполнения объекта.

public class MyClass
{
    public MyClass(Action<MyClass> populator)
    {
        populator.Invoke(this);
    }

    public int MyInt { get; set; }
    public void DoSomething() 
    {
        Console.WriteLine(this.MyInt);
    }
}

Теперь вы можете использовать это так.

var x = new MyClass(mc => { mc.MyInt = 1; mc.DoSomething(); });
1 голос
/ 10 июня 2009

В основном Эндрю пытался сказать, что если у вас есть класс (например, MyObject) с N свойствами, используя синтаксис Object Initializer C # 3.0, вы можете установить любое подмножество N свойств следующим образом:

MyObject x = новый MyObject {Property1 = 5, Property4 = "test", PropertyN = 6.7};

Вы можете установить любое из свойств / полей таким образом ./

0 голосов
/ 10 июня 2009
class MyObject
{
     public MyObject(params Action<MyObject>[]inputs)
     {
          foreach(Action<MyObject> input in inputs)
          {
               input(this);
          }
     }
}

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

...