静态方法和访问变量的能力

时间:2015-03-04 03:45:18

标签: c# static

我试图从静态方法中访问变量。我理解静态方法和非静态方法的基本概念,但仍然不能完全理解静态方法可以访问和不能访问的内容。

首先,我尝试将我的变量放在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}}

3 个答案:

答案 0 :(得分:2)

来自MSDNstatic关键字:

  

非静态类可以包含静态方法,字段,属性或事件。即使没有创建类的实例,静态成员也可以在类上调用。静态成员始终由类名访问,而不是实例名。无论创建了多少个类实例,都只存在一个静态成员的副本。静态方法和属性无法访问其包含类型中的非静态字段和事件,并且除非在方法参数中显式传递,否则它们无法访问任何对象的实例变量。

     

使用一些静态成员声明非静态类比将整个类声明为静态更典型。静态字段的两个常见用途是保持已实例化的对象数的计数,或存储必须在所有实例之间共享的值。   静态方法可以重载但不会被覆盖,因为它们属于类,而不属于类的任何实例。   虽然字段不能声明为static const,但const字段的行为基本上是静态的。它属于类型,而不属于该类型的实例。因此,可以使用与静态字段相同的ClassName.MemberName表示法来访问const字段。不需要对象实例。

     

C#不支持静态局部变量(在方法范围内声明的变量)。

静态意味着可以直接针对对象访问它而不创建实例,即class,因此可以像这样访问类Name中定义的静态成员MyClassNameMyClassName.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";

考虑到静态类和变量将一直存在,直到程序完成而不是普通类,所有对象在使用或编程完成后都将被销毁