C# 对象中静态方法和非静态方法的区别

C# 对象中静态方法和非静态方法的区别,c#,c#-6.0,C#,C# 6.0,我目前正在学习用德语书《薛定谔编程手册C#》中的C#语言编程,第156页有一个代码示例。问题是:我不明白为什么在第二种方法中使用static,而在第一种方法中不使用static 个人类别 class Person { public string Name { get; set; } public float WalkedKm { get { return this.Footsteps * 0.75f / 1000.

我目前正在学习用德语书《薛定谔编程手册C#》中的C#语言编程,第156页有一个代码示例。问题是:我不明白为什么在第二种方法中使用static,而在第一种方法中不使用static

个人类别

class Person
{
    public string Name { get; set; }
    public float WalkedKm
    {
        get
        { 
            return this.Footsteps * 0.75f / 1000.0f;
        }
    }
    public float Weight { get; set; }
    public int Footsteps { get; private set; }

    public void Walk (int Footsteps)
    {
        if (Footsteps > -1)
            this.Footsteps += Footsteps;
    }

    public static float AverageWalkedKm(Person[] persons)
    {
        int amount = persons.Length;
        float walkSum = 0;
        foreach (Person p in persons)
            walkSum += p.WalkedKm;
        return walkSum / (float)amount;
    }
} 
在主方法中

Person p1 = new Person();
Person p2 = new Person();
p1.Name = "Schrödinger";
p2.Name = "Schrödingers Girlfriend";
p1.Walk(1500);
p2.Walk(1500);
p2.Walk(2100);
Person[] person = new Person[] { p1, p2 };
Console.WriteLine("Schrödingers steps: {0}. km {1}", p1.Footsteps, p1.WalkedKm);
Console.WriteLine("Her steps: {0}. km {1}", p2.Footsteps, p2.WalkedKm);
float average = Person.AverageWalkedKm(person);
Console.WriteLine("Average: {0}km", average);
Console.ReadKey();

请帮我理解其中的区别

因为您使用的足迹变量不是静态的

float AverageWalkedKm(Person[]persons)
可以是静态的,因为它不尝试访问类的任何实例成员(字段、属性或方法)

void Walk(int footprints)
不能是静态的,因为它确实访问类的实例成员。(即
足迹
属性。)

注意:实例成员=非静态成员

编辑

因此,您反对在
AverageWalkedKm()
Person[/persons
参数的数据类型为
Person
,因此您认为它正在访问实例成员


是的,它正在访问实例成员,但不是自己实例的。给出了它所使用的实例。因此,这个方法可能属于一个完全不同的类,它仍然可以工作,没有改变,因为它被赋予了
Person
的实例来调用。当我们说实例方法能够访问实例成员时,我们指的是它自己的实例的,如
this.member
,或者甚至没有
this.
,因为它是可选的。

当您不需要(或想要)类的对象实例时,您使用静态方法。在您的示例中,无论是否创建了Person类的对象实例,都可以调用Person.AverageWalkedKm方法。但是,由于Walk方法引用实例变量(footprints),因此它不能是静态的:必须首先创建Person类的实例(示例中的p1和p2),然后使用这些实例来调用Walk方法

WalkedKm未声明为静态,因为它需要访问其调用的类的实例的状态(this.footprints)。AverageWalkedKm可以是静态的,因为它不使用类中存储的任何状态。静态被认为是更好的选择,因为您不需要创建它所附加到的类的实例,也不需要用只与其内部逻辑松散耦合的方法将其弄乱。您应该用“非静态的类的任何成员字段、属性或方法”来更正您的句子,或者“这不属于某个特定实例”或类似的内容。好的。但是在AverageWalkedKm方法参数Person[]persons中有一个数据类型为“Person”的数组,这不是在试图访问任何实例成员吗?@RafaelFarcher好的,我明白你的困惑所在。我修改了我的答案。Main method
p1.MoveRight();//非静态int-playerLife=Player.HowMuchLifeDoIHave(p1);//static
类Player public void MoveRight(){//Left this.X+=4;}public static int-HowMuchLifeDoIHave(玩家p1){return p1.Life;}这在逻辑上正确吗?是的,尽管我不喜欢你选择的命名。如果它是静态的,那么它就没有“自我”的概念,所以我不会使用“我”这个词“另外,让
播放器
实例告诉你它有多少生命是一个更好的设计,因此
有多少生命()
适合作为实例方法。