对 C# 中的 public、static 和 private methods/classes/variables 感到困惑

Confused about public, static and private methods/classes/variables in C#

我是 C# 编程的初学者,有 Python 背景。

我对关键字 public 和静态感到困惑。有人可以为我澄清一下区别吗?

(顺便说一句,我已经知道 Private variables/methods 永远不能在函数外访问,而 Public 可以)

这只是我随机尝试了解静态方法和非静态方法之间区别的一些东西。

using System;

public class MainClass
{
    public static void Main ()
    {
        int[] anArray =  getAnArray();

        foreach (int x in anArray) 
        {
            Console.WriteLine (x);
        }

        MainClass m = new MainClass ();
        foreach (int x in anArray) 
        {
            m.Print(x);
        }
    }

    public static int[] getAnArray() 
    {
        int[] myArray = { 1, 2, 3, 4 };
        return myArray;
    }

    public void Print(int x) 
    {
        Console.WriteLine(x);
    }
}

我了解要使用非静态方法 Print,我首先需要创建 MainClass 的实例,然后通过执行 m.Print()

访问该方法

但是我不明白什么时候使用哪个。据我所知,如果 Print 是静态的,那会容易得多,因为我不需要创建自己函数的新实例。

例如,这会更简单

private static void Print(int x)
{
    Console.WriteLine (x);
}

并使用 Print(x) 调用 Print 函数,而不是先创建 Main 的实例。

所以基本上什么时候用什么?什么时候不仅对方法而且对变量甚至 classes 使用静态或非静态? (例如,我什么时候应该使用 public static class MainClass)

static 成员是 class 成员,并在该 class 的所有实例之间共享。

public methods/properties 可供其他 class 使用。可以有一个 public static 成员可供其他 classes 使用。

您不能从静态成员访问非静态成员。

如果一个函数不需要访问任何实例变量,那么它可以static以获得轻微的性能提升,但还有更多有用的方法来使用静态成员。

静电的一些用途:

  • 单例(您创建一个受保护的构造函数,该构造函数由 class 中的静态变量访问)
  • Console.WriteLine 是静态的
  • Locks/semaphores(所有实例共享的 class 级别只有一个)

如果某物由 class 的所有实例共享是有意义的,请将其设为静态

public/non-static 和使用中的静态方法的自解释小示例:

Car car1 = new Car();
car1.setBrand("Ford"); //public non-static method
Car car2 = new Car();
car2.setBrand("Opel"); //public non-static method

Car.CompareParameters(car1, car2); //static method

基本上,非静态方法和属性描述了此类 class 的对象。

您不能调用 Car.setBrand() - 使用 class 名称的非静态方法。

一般经验法则:

静态方法 static 关键字使方法可以直接访问,而无需创建对象的实例。因此,它具有的任何状态或副作用都将是 static,即 "global"。因此,仅使用 static 来创建纯函数,即仅从其输入派生 return 值的方法,既不从方法外部读取也不写入状态。

static的使用是简化代码和测试之间的权衡。您在 static 方法中添加的副作用越多,您的代码就越难测试。

public 方法 任何标记为 public 的内容都可以在整个应用程序中访问。标记某些东西 internal 将其限制为仅该程序集(您可以将术语 "assembly" 视为等同于您的解决方案中的项目”)并且 private 将其限制为只能在 class/struct.

如果遵循封装原则,那么遵循的规则就是一直使用private,只在需要时才使用internal。并且只有在确实需要时才使用 public