C# 这是一个错误还是应该以这种方式工作?

C# is this a bug or is this suppose to work this way?

我正在做其他事情,遇到了这个问题。下面是一个基本示例。我相信我不应该能够访问 x 或 y。

public class Test
{
    private int x = 5;
    private int y = 10;

    public void TestBug()
    {
        Test test = new Test();
        // Why can I access x and y
        Console.WriteLine(test.x);
        Console.WriteLine(test.y);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Test Sample = new Test();
        Sample.TestBug();
        Console.ReadLine();
    }
}

不,这是正确的行为。您的代码在 Test 中,私有变量可由 Test.

中的代码访问

这与在本地方法或委托中捕获变量没有什么不同。可能出乎意料,但符合语言。

试试这个代码:

public class Test
{
    private int x = 5;
    private int y = 10;

    public void TestNotABug()
    {
        Test test = new Test();
        
        int z = 3;
        
        int Computation(int w)
        {
            return test.x + test.y + z + w;
        }
        
        Console.WriteLine(Computation(42));
    }
}

它按预期输出 60


下面是一个更具体的示例,说明您可以在哪里使用此功能:

public class Example : IEquatable<Example>
{
    private int x;
    private int y;

    public bool Equals(Example other) =>
        this.x == other.x
        && this.y == other.y;
}

如果你真的想大开眼界,试试这个例子:

void Main()
{
    var p = Person.Create("Satan", true);
    Console.WriteLine(p);
}

public abstract class Person
{
    private string _name;
    
    public static Person Create(string name, bool isEvil)
    {
        return isEvil ? new EvilPerson(name) : new EvilPerson(name);
    }
    
    protected Person(string name)
    {
        _name = name;
    }

    private class EvilPerson : Person
    {
        public EvilPerson(string name) : base(name) { }
        public override string ToString() => $"^^^{_name}^^^";
    }

    private class GoodPerson : Person
    {
        public GoodPerson(string name) : base(name) { }
        public override string ToString() => $"!!!{_name}!!!";
    }
}

那是访问父class的私有字段!它在正确的范围内,因此有效。

这输出 ^^^Satan^^^.