【问题标题】:Static Methods and ability to access variables静态方法和访问变量的能力
【发布时间】:2015-03-04 03:45:18
【问题描述】:

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

起初我试图将变量放在程序类的顶部,正如您从我的一些注释掉的行中看到的那样。我无法从我的静态方法中访问它们,因为我了解了更多关于静态的知识。但后来我把变量放在静态方法中。这是我不明白的。在静态方法中,我可以设置fs = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);,但是一旦在if 语句之外,当我在静态方法中使用FileStream fs 时,sw = new StreamWriter(fs) 给了我一个错误。尝试将其设为静态,如您在静态方法内的注释行中所见,但这也不起作用。我似乎能够访问我的变量的唯一方法是,如果我在 Program 类中(在静态方法之外)将它们设为静态。

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");

    }
}

【问题讨论】:

  • “一个错误”非常模糊。
  • 规则很简单:静态方法只能访问静态成员。在任何方法中声明的任何变量都没有访问限制,无论该方法是否是静态的。

标签: c# static


【解决方案1】:

来自MSDNstatic 关键字:

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

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

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

静态意味着可以直接针对对象访问它而无需创建实例,即class,因此可以像这样访问类MyClassName中定义的静态成员NameMyClassName.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,现在可能有人引用了类中的文件流,而另一个人可能持有对不再设置的 original 文件流的引用班级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() {
    //...
    }
}

【讨论】:

    【解决方案2】:

    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");    
    }
    

    【讨论】:

      【解决方案3】:

      静态类和方法只能访问和调用静态变量。

       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";
      

      考虑到静态类和变量在程序完成之前将是活动的,而不是普通类,所有对象在使用或程序完成后都将被销毁

      【讨论】:

        猜你喜欢
        • 2015-07-22
        • 2012-06-29
        • 2014-04-01
        • 2016-09-21
        • 1970-01-01
        • 2017-01-13
        • 1970-01-01
        • 2011-07-04
        • 2012-07-17
        相关资源
        最近更新 更多