在课堂上开课的正确方法是什么?我应该将StreamWriter放入方法中吗?或者这很好吗?
class Class1
{
public static string config = "file.config";
StreamWriter writer = new StreamWriter(config);
public void print (string log)
{
writer.WriteLine(log);
}
public void log_close()
{
writer.Close();
}
}
答案 0 :(得分:2)
您的结算逻辑不是线程安全的,不遵循建议。
您应该使用Disposable模式,因为FileStream实现了IDisposable。
class Class1 : IDisposable
{
public string config = "file.config";
StreamWriter writer = new StreamWriter(config);
public void print (string log)
{
writer.WriteLine(log);
}
public void log_close()
{
Dispose();
}
public void Dispose()
{
if (writer != null)
writer.Close();
writer = null;
}
}
现在,您的Class1实例可以与using
语句一起使用:
using (var c = new Class1())
{
c.print("That's all");
}
无需调用Dispose()或close()。
答案 1 :(得分:1)
请考虑以下代码:
class LogWriter : IDisposable
{
public const string configFileName = "file.config";
StreamWriter writer = new StreamWriter(configFileName);
public void Print(string log)
{
writer.WriteLine(log);
}
public void CloseLog()
{
writer.Close();
}
public void Dispose()
{
CloseLog();
}
}
如果你有一些资源,应该发布(比如文件),好的方法就是实现IDisposable
接口。你班上的用户都知道,该课程应在使用后处理。
同样命名 - 在C#中我们命名方法PascalCase。并为您的类和变量提供更有意义的名称:LogWriter而不是Class1,configFileName而不是config。
答案 2 :(得分:0)
你在做什么并没有错。除非您稍后需要将writer
重新初始化为新对象,否则没有理由将其放入方法中。
但是,编写它的方式是允许更改config
字符串。此时,您似乎希望将writer
的实例化移动到方法中,以便您可以在首次使用时以及config
字符串更改时实例化新的实例。但是,如果在构造类之后不需要更改config
,则应该在构造函数中请求文件名并在那里实例化对象:
class Logger : IDisposable
{
StreamWriter writer;
public void Logger(string configFileName)
{
writer = new StreamWriter(configFileName);
}
public void Print(string text)
{
writer.WriteLine(text);
}
public void Dispose()
{
writer.Dispose();
}
}
正如其他人所指出的那样,建议你的类实现IDisposable
并使用更好的命名约定。
答案 3 :(得分:0)
您已在本地类的私有范围内声明了StringWriter。这通常在多个方法之间共享变量时完成。但是,您应该管理公共变量,尤其是那些实现IDisposable的变量,例如StringBuilder。
当您使用两种方法访问StringBuilder时,可以在该范围内声明它。但是,当垃圾收集器破坏对象时,应手动关闭并处置对象。
您可以使用C#类析构函数,详细信息为here。
答案 4 :(得分:-1)
初始化的字段的初始化将在编译时移动到构造函数的顶部。
class Class1
{
String foo = "bar";
String bar;
public Class1()
{
bar = "baz";
}
}
变为
.class private auto ansi beforefieldinit FieldInitialization.Class1
extends [mscorlib]System.Object
{
.field private string bar
.field private string foo
.method public hidebysig specialname rtspecialname
instance void .ctor () cil managed
{
IL_0000: ldarg.0
IL_0001: ldstr "bar"
IL_0006: stfld string FieldInitialization.Class1::foo
IL_000b: ldarg.0
IL_000c: call instance void [mscorlib]System.Object::.ctor()
IL_0011: nop
IL_0012: nop
IL_0013: ldarg.0
IL_0014: ldstr "baz"
IL_0019: stfld string FieldInitialization.Class1::bar
IL_001e: nop
IL_001f: ret
}
}
因此,选择初始化它们的风格确实很重要。但是,当您要初始化的对象依赖于其他非静态字段,方法或属性时,您必须在构造函数中初始化它们。否则你将得到编译错误:
字段初始值设定项不能引用非静态字段,方法或属性
对于像StreamWriter这样的IDispisable资源(例如Bitmap),您应该记住其他人指出的问题。