是否有可能使用C#对象初始化一个工厂方法? [英] Is it possible to use a c# object initializer with a factory method?

查看:172
本文介绍了是否有可能使用C#对象初始化一个工厂方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有上有一个静态工厂方法的类。我想打电话给厂里来检索类的实例,然后再做额外的初始化,通过C#的对象初始化语法preferablly:

  MyClass的实例= MyClass.FactoryCreate()
{
someProperty = someValue中;
}



VS

  MyClass的实例= MyClass.FactoryCreate(); 
instance.someProperty = someValue中;


解决方案

没有。另外,您可以接受一个lambda作为参数,这也给了你充分的控制,其中,创作过程的一部分将被调用。这样,你可以这样调用它:

  MyClass的实例= MyClass.FactoryCreate(C => 
{
c.SomeProperty =东西;
c.AnotherProperty = somethingElse;
});



创建将类似于:

 公共静态MyClass的FactoryCreate(动作< MyClass的> initalizer)
{
MyClass的MyClass的=新MyClass的();
//做的东西
初始化(MyClass的);
//做更多的东西
返回MyClass的;
}






另一种选择是返回一个助洗剂代替(具有一个隐含的铸造操作者MyClass的)。你会叫这样的:

  MyClass的实例= MyClass.FactoryCreate()
.WithSomeProperty(东西)
.WithAnotherProperty(somethingElse);

检查的的建设者



这两个版本在编译时检查,并有充分的IntelliSense支持。






这需要一个默认的构造函数第三个选项:

  //使用,如:
VAR数据= MyClass.FactoryCreate(()=>新建数据
{
DESC =东西,
ID = 1
});
//实现为:
公共静态MyClass的FactoryCreate(表达式来; Func键< MyClass的>>初始化)
{
变种MyClass的=新MyClass的();
ApplyInitializer(MyClass的,(MemberInitExpression)initializer.Body);
返回MyClass的;
}
//使用这个:
静态无效ApplyInitializer(对象实例,MemberInitExpression initalizer)
{
的foreach(在initalizer.Bindings.Cast< VAR结合; MemberAssignment> ())
{
VAR道具=(的PropertyInfo)bind.Member;
VAR值=((常量表达式)bind.Expression).value的;
prop.SetValue(例如,值,NULL);
}
}



它在编译时检查,没有检查之间的中间。它需要一些工作,因为它迫使在分配常量表达式。我认为,任何东西都已经在答案的方法的变体。请记住,您也可以使用正常的分配,考虑,如果你真的需要任何这一点。


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# object initializer syntax :

MyClass instance = MyClass.FactoryCreate()
{
  someProperty = someValue;
}

vs

MyClass instance = MyClass.FactoryCreate();
instance.someProperty = someValue;

解决方案

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<MyClass> 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<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);
    }
}

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.

这篇关于是否有可能使用C#对象初始化一个工厂方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆