为什么“static”关键字需要在 C# 中的程序类中

本文关键字:程序 static 关键字 为什么 | 更新日期: 2023-09-27 18:33:06

我不知道为什么当我不使用"static"时,函数有错误:

"An object reference is required for non-static field,method, or property.Dos2Unix(string)"

代码如下所示:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
    static void Main(string[] args)
    {
        var f = @"'D:'temp'test.xls";
        Dos2Unix(f);
    }
    private void Dos2Unix(string fileName)
    {
       const byte CR = 0x0D;
       const byte LF = 0x0A;
       byte[] data = File.ReadAllBytes(fileName);
       using (FileStream fileStream = File.OpenWrite(fileName))
       {
           BinaryWriter bw = new BinaryWriter(fileStream);
           int position = 0;
           int index = 0;
           do
           {
             index = Array.IndexOf<byte>(data, CR, position);
             if ((index >= 0) && (data[index + 1] == LF))
             {
               // Write before the CR
               bw.Write(data, position, index - position);
               // from LF
               position = index + 1;
             }
           }
                while (index > 0);
                bw.Write(data, position, data.Length - position);
                fileStream.SetLength(fileStream.Position);
            }
    }
 }
}

当我使用关键字"静态"时,没有错误。

不确定我犯了什么错误。需要一些帮助。

为什么“static”关键字需要在 C# 中的程序类中

调用非静态方法时this参数隐式传递到方法

  private void Dos2Unix(string fileName) {
    ...
    var sample = this.GetType(); // <- possible call
    ...
  }

静态方法无法提供此类参数(this),因此出现错误。在您的情况下,您不希望Dos2Unix方法中的类实例Program因此将其设置为静态:

  class Program 
  {
    static void Main(string[] args)
    {
        var f = @"'D:'temp'test.xls";
        Dos2Unix(f);
    } 
    // Please, note "static"
    private static void Dos2Unix(string fileName) 
    {
      ...
    }
  }

从技术上讲,您根本不想要Program类实例,因此将整个类声明为 static

   // class is static
   static class Program 
   {
      static void Main(string[] args)
      {
        var f = @"'D:'temp'test.xls";
        Dos2Unix(f);
      } 
      // all methods are static
      private static void Dos2Unix(string fileName) 
      {
       ...
      }
   }

不能直接从静态方法调用非静态方法,因为程序类的 Main 方法是静态的,只能从此方法调用程序类的静态方法。

要从 Main 方法调用非静态方法,

您可以创建程序类的对象并在此对象上调用非静态方法。

static void Main(string[] args)
{
    var f = @"'D:'temp'test.xls";
    Program p = new Program();
    p.Dos2Unix(f);
}
静态方法

不能调用非静态方法是有原因的,因为静态方法不绑定到该类的实例,另一方面非静态方法绑定到实例(可以访问非静态数据成员)。考虑一个静态方法调用一个非静态方法,该方法正在访问实际上不存在的实例成员,因为静态方法是在类而不是实例上调用的。您可以在这篇文章中进一步阅读。

如果要从静态方法Main调用非静态方法,则必须创建一个类型为Program的新对象:

new Program().Dos2Unix(f);

你需要创建类的实例。这应该有效:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
    static void Main(string[] args)
    {
        Program p = new Program();
        var f = @"'D:'temp'test.xls";
        p.Dos2Unix(f);
    }
    private void Dos2Unix(string fileName)
    {
       const byte CR = 0x0D;
       const byte LF = 0x0A;
       byte[] data = File.ReadAllBytes(fileName);
       using (FileStream fileStream = File.OpenWrite(fileName))
       {
           BinaryWriter bw = new BinaryWriter(fileStream);
           int position = 0;
           int index = 0;
           do
           {
             index = Array.IndexOf<byte>(data, CR, position);
             if ((index >= 0) && (data[index + 1] == LF))
             {
               // Write before the CR
               bw.Write(data, position, index - position);
               // from LF
               position = index + 1;
             }
           }
                while (index > 0);
                bw.Write(data, position, data.Length - position);
                fileStream.SetLength(fileStream.Position);
            }
    }
 }
}

所以基本上你只需要添加:

Program p = new Program();

并调用您的方法,如下所示:

p.Dos2Unix("....");

这是因为您不能在静态方法中访问非静态方法(顺便说一下,您也不能使用它)。