是否可以使用工厂方法使用ac#object initializer?
我有一个带有静态工厂方法的类。 我想调用工厂来检索类的实例,然后通过c#object initializer语法进行额外的初始化:
MyClass instance = MyClass.FactoryCreate() { someProperty = someValue; }
VS
MyClass instance = MyClass.FactoryCreate(); instance.someProperty = someValue;
不然。或者您可以接受lambda作为参数,这也可以让您完全控制“创建”过程的哪一部分将被调用。 这样你就可以这样称呼它:
MyClass instance = MyClass.FactoryCreate(c=> { c.SomeProperty = something; c.AnotherProperty = somethingElse; });
创建看起来类似于:
public static MyClass FactoryCreate(Action 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> 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); } }
它是在编译时检查而未检查的中间。 它确实需要一些工作,因为它强制在赋值上不断表达。 我认为其他任何东西都是答案中已有方法的变体。 请记住,您也可以使用正常的作业,考虑是否真的需要这些作业。
您可以使用扩展方法,如下所示:
namespace Utility.Extensions { public static class Generic { /// /// Initialize instance. /// public static T Initialize(this T instance, Action initializer) { initializer(instance); return instance; } } }
您可以这样称呼它:
using Utility.Extensions; // ... var result = MyClass.FactoryCreate() .Initialize(x => { x.someProperty = someValue; x.someProperty2 = someValue2; });
关于“否”的+1。
这是匿名对象方式的替代方法:
var instance = MyClass.FactoryCreate( SomeProperty => "Some value", OtherProperty => "Other value");
在这种情况下, FactoryCreate()
将类似于:
public static MyClass FactoryCreate(params Func
不,对象初始值设定项只能在使用构造函数调用“new”时使用。 一种选择可能是在工厂方法中添加一些额外的args,以便在工厂内创建对象时设置这些值。
MyClass instance = MyClass.FactoryCreate(int someValue, string otherValue);
像所有人说的那样,没有。
已经提出了lambda作为论据。
更优雅的方法是接受匿名并根据对象设置属性。 即
MyClass instance = MyClass.FactoryCreate(new { SomeProperty = someValue, OtherProperty = otherValue });
但这会慢得多,因为对象必须反映在所有属性上。
不,那是你只能做’内联’的事情。 所有工厂function都可以为您做的是返回参考。