Protection level of a struct field within a class

2019-02-16 18:49发布

问题:

I am fairly new to C# programming so this is likely a beginner's question.

I get a "'A.Test.That.Fails' is inaccessible due to its protection level" error on the following code snippet and I fail to understand the reason.

namespace A
{
    class Test
    {
        public void Demo()
        {
            That[] it = new That[42];
            it[0].fails = 21;
        }

        public struct That
        {
            int fails;
        }
    }
}

Coming from C++ programming and having read that protection rules are almost the same, since there is a single class I would expect it to work even if both the That struct and the Demo method were private.

As the side note, a link to some page summing up scope and protection rules toward the C++ programmer would be greatly appreciated.

回答1:

The other answers given already have your answer, so I won't beat a dead horse here. You need to declare the field public in order to be able to access it from external code.

In C++, structs and classes are equivalent, with the only difference being the default access level of their respective members.

However, that's not the case in C#. Generally, you should only use a struct for small, short-lived objects that are immutable (won't change). A structure has value type semantics, where as a class has reference type semantics. It's very important that you understand the difference between value types and reference types if you're learning to program in C#. Jon Skeet has published an article that attempts to provide that explanation. But you'll definitely want to pick up a good introductory book to C# that treats these issues in more detail.

More often than not, you'll want to use a class in C#, rather than a structure. And when you use that class, note that Microsoft's design guidelines for C# tend to recommend against exposing public fields. Instead, they recommend that you use a public property, backed by a private field. A more thorough exposition of the rationale behind that guideline is given here. For example:

class TimePeriod
{
    private double seconds;

    public double Seconds
    {
        get { return seconds; }
        set { seconds = value; }
    }
}

Or you can use the simpler "automatic properties" syntax, which has the compiler automatically generate that private backing field:

class TimePeriod
{
    public double Seconds { get; set; }
}


回答2:

The default access modifier in C# for struct fields (and class fields) is private. So int fails; is private to your struct, unless you declare it public.



回答3:

please see the answer to this question

That member is being declared private by default - you need to put the public modifier before it.



回答4:

Because fails is not public.. by default fields in struct and even class are private

According to MSDN

The access level for class members and struct members, including nested classes and structs, is private by default.



回答5:

Private members of Test restrict to Test itself and are not available outside of Test. Demo is outside of Test. It doesn't matter who the parent is.

Define Demo inside Test and you can access the private members.