Действительно ли возможно использовать инициализатор объекта c# с методом фабрики?

Это должно быть countMe, а не countMe.Increment(), так как вы назначаете возвращаемое значение функции для countMe

function enclosedFunction(){
  var counter = 0;
  var Increment = function(){
    counter ++;
    console.log(counter);
    }
  return(Increment);
}

var countMe = enclosedFunction();
console.log("Count Me: ");
countMe();

Если вы хотите получить доступ с точечной нотацией, вам нужно использовать объект

function enclosedFunction(){
  var counter = 0;
  var Increment = function(){
    counter ++;
    console.log(counter);
    }
  return(Increment);
}

var countMe =  {}
countMe.Increment = enclosedFunction();
console.log("Count Me: ");
countMe.Increment();

26
задан Jason Coyne 23 March 2009 в 22:55
поделиться

5 ответов

Нет. Кроме того, Вы могли принять лямбду как аргумент, который также дает Вам полный контроль, в котором назовут часть процесса "создания". Таким образом, можно назвать его как:

MyClass instance = MyClass.FactoryCreate(c=>
   {
       c.SomeProperty = something;
       c.AnotherProperty = somethingElse;
   });

Создавание выглядело бы подобным:

public static MyClass FactoryCreate(Action<MyClass> initalizer)
{
    MyClass myClass = new MyClass();
    //do stuff
    initializer( myClass );
    //do more stuff
    return myClass;
}

Другая опция состоит в том, чтобы возвратить разработчика вместо этого (с неявным оператором броска в MyClass). Как который Вы звонили бы:

MyClass instance = MyClass.FactoryCreate()
   .WithSomeProperty(something)
   .WithAnotherProperty(somethingElse);

Проверьте это на разработчика

Обе из этих версий проверяются во время компиляции и имеют полную поддержку intellisense.


Третья опция, которая требует конструктора по умолчанию:

//used like:
var data = MyClass.FactoryCreate(() => new Data
{
    Desc = "something",
    Id = 1
});
//Implemented as:
public static MyClass FactoryCreate(Expression<Func<MyClass>> initializer)
{
    var myclass = new MyClass();
    ApplyInitializer(myclass, (MemberInitExpression)initializer.Body);
    return myclass ;
}
//using this:
static void ApplyInitializer(object instance, MemberInitExpression initalizer)
{
    foreach (var bind in initalizer.Bindings.Cast<MemberAssignment>())
    {
        var prop = (PropertyInfo)bind.Member;
        var value = ((ConstantExpression)bind.Expression).Value;
        prop.SetValue(instance, value, null);
    }
}

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

28
ответ дан eglasius 28 November 2019 в 07:33
поделиться

+1 на "Нет".

Вот является альтернатива анонимному объекту путем:

var instance = MyClass.FactoryCreate(
    SomeProperty => "Some value",
    OtherProperty => "Other value");

В этом случае FactoryCreate() было бы что-то как:

public static MyClass FactoryCreate(params Func<object, object>[] initializers)
{
    var result = new MyClass();
    foreach (var init in initializers) 
    {
        var name = init.Method.GetParameters()[0].Name;
        var value = init(null);
        typeof(MyClass)
            .GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase)
            .SetValue(result, value, null);
    }
    return result;
}
2
ответ дан Paul Stovell 28 November 2019 в 07:33
поделиться

Нет, объектный инициализатор может только привыкнуть на вызове к "новому" с конструктором. Одна опция могла бы состоять в том, чтобы добавить некоторый дополнительный args к Вашему методу фабрики, установить те значения при создании объекта в фабрике.

MyClass instance = MyClass.FactoryCreate(int someValue, string otherValue);
1
ответ дан Andy White 28 November 2019 в 07:33
поделиться

Как все сказал, нет.

Лямбда как аргумент была уже предложена.
Более изящный подход должен был бы принять анонимное и устанавливать свойства согласно объекту. т.е.

MyClass instance = MyClass.FactoryCreate(new {
    SomeProperty = someValue,
    OtherProperty = otherValue
});

Это было бы намного медленнее, хотя, так как над объектом нужно будет размышлять для всех свойств.

1
ответ дан configurator 28 November 2019 в 07:33
поделиться

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

0
ответ дан Trap 28 November 2019 в 07:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: