我刚刚更新了Visual Studio 2013,我注意到在MVC应用程序的项目模板中,ApplicationDbContext类现在有一个只调用构造函数的静态方法:
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
这对我来说似乎很混乱,但我想有一些语义原因我现在应该开始使用ApplicationDbContext.Create()
而不是new ApplicationDbContext()
。这样做有什么好处吗?
答案 0 :(得分:17)
实际上。是
在您的特定情况下,通过它包装它可以让您快速开始使用逻辑,例如制作ApplicationDbContext和singleton或以整个应用程序的通用方式处理异常。由于构造函数不能返回null,因此能够捕获异常并返回null非常重要。
Tuple.Create是泛型推理的主要示例,它不适用于构造函数。这允许你说
Tuple.Create(Item1, Item2.. ItemN);
让编译器推断类型,而不是
new Tuple<T1, T2...Tn>(Item1, Item2...ItemN);
哪个更详细,如果你想切换其中一种类型,需要做更多的工作。
还存在匿名类型的情况,无法明确指定,因此不能在新语句中使用。我特意有机会在搜索特定属性的程序集以链接命令结构时,我想在搜索期间使用匿名类型创建一个可枚举的(在本例中为一个Queue),以便将类引用与其构造函数配对和字符串参数,而不是每次他们需要时查找这些参数。由于我可以在方法中再次使用Generic推理,因此我能够将构造函数包装在扩展方法中并完成工作。
还有单例模式的情况,其中你需要&#34; GetInstance&#34;通常创建值的方法,如果存在则获取值。可能不符合条件,因为它比包装构造函数稍微多一点。
此外,在很多情况下,您可能希望控制实现过程,例如将它们强制转移到其他线程,将它们记录在数据库中以便稍后撤消,或者在权限系统上进行操作,所有这些都可以通过制作构造函数包装器并添加更多逻辑行,然后对构造函数进行私有化以避免直接调用它来完成。
在某些情况下,我创建了一个工厂方法,该方法委托给已知的子级,以便根据提供的参数提供返回接口或抽象的不同实现。这具有能够隐藏实现类的额外好处--Type类和IEnumerable接口使用此模式。
答案 1 :(得分:6)
此模式非常有用,特别是如果您使用私有构造函数,并从Create返回接口类型,而不是具体类型。
private ApplicationDbContext()
{
}
public static IApplicationDbContext Create()
{
return new ApplicationDbContext();
}
现在,您的班级消费者无法依赖具体实施 - 他们只能依赖抽象。
答案 2 :(得分:0)
使用静态方法(创建方法)包装构造函数允许您选择传达信息的特定名称。您还可以使用相同的参数签名创建多个方法,例如CreateX(float f)
和CreateY(float f)
,这是构造函数无法做到的。
这种情况非常有用,例如:用于创建表示可能具有多个单位的物理量的结构,例如时间,长度或重量。在这里,您可以使用创建方法来强制程序员始终显式指定单元,而不是仅将单位数传递给单个构造函数(假定某个单位,并且错误可能有huge consequences)。
示例:
public struct Length
{
private const double MetersPerYard = 0.9144;
private double _meters;
private Length(double meters)
{
_meters = meters;
}
public static Length FromMeters(double meters)
{
return new Length(meters);
}
public static Length FromYards(double yards)
{
return new Length(yards*MetersPerYard);
}
public double Meters
{
get { return _meters; }
}
public double Yards
{
get { return _meters / MetersPerYard; }
}
}
或者查看TimeSpan
以及FromMinutes
,FromSeconds
等方法。