我试图从静态方法中访问变量。我理解静态方法和非静态方法的基本概念,但仍然不能完全理解静态方法可以访问和不能访问的内容。
首先,我尝试将我的变量放在Program Class的顶部,正如您从一些注释掉的行中看到的那样。我无法从我的静态方法访问它们,因为我学到了更多关于静态的意义。但后来我把变量放在静态方法中。这是我不明白的。在静态方法中我可以设置fs = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);
但是在if语句之外,当sw = new StreamWriter(fs)
在静态方法中有FileStream fs
时,class Program {
static FileStream fs;
// public bool fileopen = false;
// String filename = @"D:\Stock Trading\Test1.txt";
static void Main(string[] args) {
CreateDebugFile();
}
public static void CreateDebugFile() {
StreamWriter sw;
bool fileopen = false;
// static FileStream fs;
String filename = @
"D:\Stock Trading\Test1.txt";
if (!fileopen) {
fs = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);
fileopen = true;
}
sw = new StreamWriter(fs);
sw.Write("Current Bar" + "\t" + "time" + "\t" + "Open" + "\t" + "Close" + "\t" + "Low" + "\t" + "High");
}
}
给了我一个错误。尝试将其设置为静态,如静态方法中注释掉的行所示,但这也不起作用。我似乎能够访问我的变量的唯一方法是,如果我在Program类中使它们静态(在静态方法之外)。
{{1}}
答案 0 :(得分:2)
来自MSDN的static
关键字:
非静态类可以包含静态方法,字段,属性或事件。即使没有创建类的实例,静态成员也可以在类上调用。静态成员始终由类名访问,而不是实例名。无论创建了多少个类实例,都只存在一个静态成员的副本。静态方法和属性无法访问其包含类型中的非静态字段和事件,并且除非在方法参数中显式传递,否则它们无法访问任何对象的实例变量。
使用一些静态成员声明非静态类比将整个类声明为静态更典型。静态字段的两个常见用途是保持已实例化的对象数的计数,或存储必须在所有实例之间共享的值。 静态方法可以重载但不会被覆盖,因为它们属于类,而不属于类的任何实例。 虽然字段不能声明为static const,但const字段的行为基本上是静态的。它属于类型,而不属于该类型的实例。因此,可以使用与静态字段相同的ClassName.MemberName表示法来访问const字段。不需要对象实例。
C#不支持静态局部变量(在方法范围内声明的变量)。
静态意味着可以直接针对对象访问它而不创建实例,即class
,因此可以像这样访问类Name
中定义的静态成员MyClassName
: MyClassName.Name
(而不是new MyClassName().Name
),当您从该类中访问静态成员时,您可以使用Name
,但编译器处理的类似于您从外部访问它班级。
虽然静态值没有变化,但是在应用程序中调用该静态属性的任何人都在访问同一个实例,如果可以从类外部更改该值,则可能导致并发问题。
采用以下示例:
public class MyClassName
{
public static string FilePath = @"C:\Temp";
public static FileStream fs;
public static void CreateFileStream()
{
//creates a file stream
}
}
如果两个人同时调用相同的方法MyClassName.CreateFileStream()
,那么首先进入该方法的人会创建一个文件流并将其设置为fs
,然后第二个人创建一个文件流并将其设置为fs
,现在有人可能会引用该类中的文件流,而另一个可能会继续引用原始文件流不再在课程MyClassName
上设置。
因此,您需要注意如何暴露静态成员(在您的具体示例中不是问题,但要记住这一点很重要)。如果你声明一个静态字段,你应该确保实例化它或将它保持为类的私有,这样你就可以确定它是否被实例化以便使用它。
在你的情况下,每次调用该方法时都会创建一个新的文件流,因为bool fileopen
在方法内部,方法内部的任何内容只能在该方法内部使用,无论是否为静态,并且每次调用该方法时都会再次创建,并且您需要在要从另一个静态字段,属性或方法调用的字段或属性或方法的每个声明上使用static
关键字。
class Program {
static FileStream fs; //needs to be static
public static bool fileopen = false; //needs to be static
static String filename = @"D:\Stock Trading\Test1.txt";
//needs to be static, or this one could also be
//const if it will never change
static void Main(string[] args) {
CreateDebugFile();
}
public static void CreateDebugFile() {
//...
}
}
答案 1 :(得分:0)
<强> 1。我无法通过静态方法访问它们
静态方法不能使用实例变量。它只能使用局部变量(在变量内声明)和该类或其他类的静态变量。
所以
public static bool fileopen = false;
static String filename = @"D:\Stock Trading\Test1.txt";
会起作用
<强> 2。但在if语句之外,
sw = new StreamWriter(fs)
给了我一个错误
那是因为你没有初始化变量fs。你必须在使用前初始化它。
public static void CreateDebugFile() {
StreamWriter sw = null; //would remove compile time error but beware of null reference exception :)
bool fileopen = false;
String filename = @
"D:\Stock Trading\Test1.txt";
if (!fileopen) {
fs = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);
fileopen = true;
}
sw = new StreamWriter(fs);
sw.Write("Current Bar" + "\t" + "time" + "\t" + "Open" + "\t" + "Close" + "\t" + "Low" + "\t" + "High");
}
答案 2 :(得分:0)
statict类和方法只能访问和调用statn变量。
static FileStream fs;
/*
you can't access to this variables from a static method,
because they are declare as instance variable, even when they are nested in the same class
*/
// public bool fileopen = false;
// String filename = @"D:\Stock Trading\Test1.txt";
//you need to add the word static at begin of declaration
public static bool fileopen = false;
static string filename = @"D:\Stock Trading\Test1.txt";
考虑到静态类和变量将一直存在,直到程序完成而不是普通类,所有对象在使用或编程完成后都将被销毁