运行 只包含一次的 class 是否应该包含静态构造函数?
Should a class that will run only once contain a static constructor?
我开始使用 C# 学习 OOP 编程。
关于设计,考虑到这个 class 包含的代码只会 运行 一次(我的整个程序非常简单,由一个 .cs 文件组成。
例如,下面是使用普通构造函数的示例代码:
class Program
{
const string file = @"C:\Program Files (x86)\myapp\log.txt";
int status;
static int Main(string[] args)
{
var myObj = new Program();
return myObj.status;
}
public Program()
{
int retCode;
try {
// lots of procedures using the file
retCode = 0; // ok
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
retCode = 999; // specific error
}
status = retCode;
}
}
这里遵循相同的结构,但使用 static
构造函数,因为我认为它已经足够了。请注意 status
访问权限也已更改。
class Program
{
const string file = @"C:\Program Files (x86)\myapp\log.txt";
static int status;
static int Main(string[] args)
{
return Program.status;
}
static Program()
{
int retCode;
try {
// lots of procedures using the file
retCode = 0;
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
retCode = 999;
}
status = retCode;
}
}
问题:我的假设是否正确,使用第二个代码而不是第一个代码?或者我错过了什么?
换句话说:哪个更好(被认为是更好的设计)?在这种情况下,静态构造函数是否有一些基础知识会给我带来麻烦?
所提供的代码做的事情完全相同,除了在第一个实例中您创建对象 Program
而不是使用静态成员。这将为您的应用程序创建额外的开销。现在在这种情况下,确实没有理由选择这两种方法中的任何一种,因为开销可以忽略不计。
然而,在第一个实例中,值 status
是基于实例的。因此只有 Program
的实例具有状态值。因此,如果 status
是一个基于实例的字段,其中 Program
的多个实例应该维护它们自己的 status
字段值,那么您应该使用第一个示例。
尽量避免使用静态构造函数。与实例构造函数不同,您不能主动调用静态构造函数 - 它是 运行 当类型第一次被使用时(这可能会由于优化甚至混淆而改变)。
同时尽量避免在构造函数中执行 "work"。构造函数旨在构造实例,仅此而已。
所以在这两种情况下,我都会将功能移至方法中。然后该方法可以具有实际的 return 值,而不是设置 属性。由于您不维护任何状态(Program.status
然后变成 return 值),您可以安全地使该方法静态化。
OP 可能正在寻找单例模式。
我个人的观点是,如果 class 只会被实例化一次,那么它一开始就没有理由成为 class,并且如果这样的 class 被还原为静态 C 函数 - 但这只是我的意见。
我开始使用 C# 学习 OOP 编程。 关于设计,考虑到这个 class 包含的代码只会 运行 一次(我的整个程序非常简单,由一个 .cs 文件组成。
例如,下面是使用普通构造函数的示例代码:
class Program
{
const string file = @"C:\Program Files (x86)\myapp\log.txt";
int status;
static int Main(string[] args)
{
var myObj = new Program();
return myObj.status;
}
public Program()
{
int retCode;
try {
// lots of procedures using the file
retCode = 0; // ok
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
retCode = 999; // specific error
}
status = retCode;
}
}
这里遵循相同的结构,但使用 static
构造函数,因为我认为它已经足够了。请注意 status
访问权限也已更改。
class Program
{
const string file = @"C:\Program Files (x86)\myapp\log.txt";
static int status;
static int Main(string[] args)
{
return Program.status;
}
static Program()
{
int retCode;
try {
// lots of procedures using the file
retCode = 0;
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
retCode = 999;
}
status = retCode;
}
}
问题:我的假设是否正确,使用第二个代码而不是第一个代码?或者我错过了什么?
换句话说:哪个更好(被认为是更好的设计)?在这种情况下,静态构造函数是否有一些基础知识会给我带来麻烦?
所提供的代码做的事情完全相同,除了在第一个实例中您创建对象 Program
而不是使用静态成员。这将为您的应用程序创建额外的开销。现在在这种情况下,确实没有理由选择这两种方法中的任何一种,因为开销可以忽略不计。
然而,在第一个实例中,值 status
是基于实例的。因此只有 Program
的实例具有状态值。因此,如果 status
是一个基于实例的字段,其中 Program
的多个实例应该维护它们自己的 status
字段值,那么您应该使用第一个示例。
尽量避免使用静态构造函数。与实例构造函数不同,您不能主动调用静态构造函数 - 它是 运行 当类型第一次被使用时(这可能会由于优化甚至混淆而改变)。
同时尽量避免在构造函数中执行 "work"。构造函数旨在构造实例,仅此而已。
所以在这两种情况下,我都会将功能移至方法中。然后该方法可以具有实际的 return 值,而不是设置 属性。由于您不维护任何状态(Program.status
然后变成 return 值),您可以安全地使该方法静态化。
OP 可能正在寻找单例模式。 我个人的观点是,如果 class 只会被实例化一次,那么它一开始就没有理由成为 class,并且如果这样的 class 被还原为静态 C 函数 - 但这只是我的意见。