Protection level of a struct field within a class

Julien Guertault picture Julien Guertault · Mar 28, 2011 · Viewed 12.2k times · Source

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.

Answer

Cody Gray picture Cody Gray · Mar 28, 2011

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; }
}