Is it possible to use a c# object initializer with a factory method?

前端 未结 7 1632
离开以前
离开以前 2020-12-25 13:06

I have a class with a static factory method on it. I want to call the factory to retrieve an instance of the class, and then do additional initialization, preferablly via c#

7条回答
  •  清酒与你
    2020-12-25 13:21

    No. Alternatively you could accept a lambda as an argument, which also gives you full control in which part of the "creation" process will be called. This way you can call it like:

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

    The create would look similar to:

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

    Another option is to return a builder instead (with an implicit cast operator to MyClass). Which you would call like:

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

    Check this for the builder

    Both of these versions are checked at compile time and have full intellisense support.


    A third option that requires a default constructor:

    //used like:
    var data = MyClass.FactoryCreate(() => new Data
    {
        Desc = "something",
        Id = 1
    });
    //Implemented as:
    public static MyClass FactoryCreate(Expression> 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())
        {
            var prop = (PropertyInfo)bind.Member;
            var value = ((ConstantExpression)bind.Expression).Value;
            prop.SetValue(instance, value, null);
        }
    }
    

    Its a middle between checked at compile time and not checked. It does need some work, as it is forcing constant expression on the assignments. I think that anything else are variations of the approaches already in the answers. Remember that you can also use the normal assignments, consider if you really need any of this.

提交回复
热议问题