Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to correctly hide helpers (inner) classes inside a class in C#

I am having problems understanding how to correctly encapsulate my class. It is (or should be) an inmutable class.

I am using a "helper class" and I want it to be not accesible from the outside.

namespace MyApp
{

    [Flags]
    public enum OctaveGroups
    {
        None = 0,
        oneOctave = 1
    }

    class Frequencies
    {
        // HelperClass
        public class Frequency
        {
            public string Name { get;  set; }
            public OctaveGroups Octave { get; set; }
        }

        public readonly static List<Frequency> All = new List<Frequency>
        {
        #region Complete Frequencies Data

                new Frequency { Name = "63", Hz = 63,
                    Octave = OctaveGroups.oneOctave | OctaveGroups.None,
                    },

                new Frequency { Name = "80", Hz = 80,
                    Octave = OctaveGroups.None,
                    }
           // And so on..
                //..

        #endregion
        };


        public readonly List<Frequency> OneOctave = All.Where(f => f.Octave.HasFlag(OctaveGroups.oneOctave)).ToList();

        public readonly List<Frequency> None = All.Where(f => f.Octave.HasFlag(OctaveGroups.None)).ToList();

    }
}

If I make my Frequency class protected or private I get this error:

Inconsistent accessibility: field type 'List' is less accesible than field 'Frequencies.All'

I get the same error if I make class Frequency and List<Frequency> Allprotected and try to make a method that returns a List<Frequency> like:

public List<Frequency> GetAll()
    {
        return All.Where(f => f.Octave.HasFlag(OctaveGroups.OneOctave)).ToList();
    } 

How will be the correct way to expose just .All .OneOctave and .None fields while keeping them read only?

like image 614
distante Avatar asked Dec 19 '25 13:12

distante


2 Answers

You can't expect to hide Frequency when you are planning in having public methods returning List<Frequency>.

Now, what I understand is your issue is that you need accessible property setters in Frequency from Frequencies but you don't want to expose them to the outside. The way to do this is through an interface that only exposes getters:

public interface IFrequency
{
    string Name { get; }
    OctaveGroups Octave { get; }  
}

And now, you make Frequencies.Frequency a private nested class and you expose only IFrequency:

class Frequencies
{
    // HelperClass
    private class Frequency: IFrequency
    {
        public string Name { get;  set; }
        public OctaveGroups Octave { get; set; }
    }

    public readonly static List<IFrequency> All = new List<IFrequency>
    {
    #region Complete Frequencies Data

            new Frequency { Name = "63", Hz = 63,
                Octave = OctaveGroups.oneOctave | OctaveGroups.None,
                },

            new Frequency { Name = "80", Hz = 80,
                Octave = OctaveGroups.None,
                }
       // And so on..
            //..

    #endregion
    };


    public readonly List<IFrequency> OneOctave = All.Where(f => f.Octave.HasFlag(OctaveGroups.oneOctave)).ToList();

    public readonly List<IFrequency> None = All.Where(f => f.Octave.HasFlag(OctaveGroups.None)).ToList();

}

Now a consumer of Frequencies will only see IFrequency instances where no setter is exposed and is therefore immutable to the outside world (excluding reflection of course).

like image 199
InBetween Avatar answered Dec 21 '25 02:12

InBetween


The correct way is not to hide them.

You simply cannot both hide and expose a class to the outside world, at the same time.

So if you want to declare a public method returning the object, or a collection of the object, you must make the type of the object in question public as well.

like image 32
Lasse V. Karlsen Avatar answered Dec 21 '25 01:12

Lasse V. Karlsen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!