如何在C#

时间:2016-12-30 23:09:18

标签: c# class class-design

我在理解如何正确封装我的课时遇到了问题。它是(或应该)一个不可改变的类。

我正在使用"帮助类"我希望它不能从外面访问。

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();

    }
}

如果我创建Frequency课程protectedprivate,我会收到此错误:

  

可访问性不一致:字段类型&#39;列表&#39;   比现场频率更低,所以&#39;

如果我class FrequencyList<Frequency> All受到保护并尝试创建一个返回List<Frequency>的方法,我会收到相同的错误:

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

如果只显示.All .OneOctave.None字段,同时保持只读字段的正确方法是什么?

3 个答案:

答案 0 :(得分:6)

当您计划让公共方法返回Frequency时,您不能指望隐藏List<Frequency>

现在,我的理解是您的问题是您需要来自Frequency的{​​{1}}中的可访问属性设置器,但您不希望将它们暴露给外部。这样做的方法是通过一个只暴露getter的接口:

Frequencies

现在,您将public interface IFrequency { string Name { get; } OctaveGroups Octave { get; } } 设为私有嵌套类,并且只公开Frequencies.Frequency

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(); } 的消费者只会看到Frequencies个实例,其中没有露出setter,因此对外界是不可变的(当然不包括反射)。

答案 1 :(得分:2)

正确的方法不是隐藏它们。

你根本无法两者同时隐藏和向外界展示一个类。

因此,如果要声明返回对象的公共方法或对象的集合,则必须将相关对象的类型设置为public。

答案 2 :(得分:-1)

尝试在Frequency类中添加内部构造函数。这将允许您从类中构造一个频率,但不允许外部类构造它。由于无法在外部构建,因此无法在课堂外添加新的,因为它们被键入频率。

示例:

public class ExternalType
    {
        public class InternalType
        {
            internal InternalType(string someString) 
            {
                SomeStringProp = someString;
            }

            public string SomeStringProp { get; private set; }
        }

        public readonly List<InternalType> InternalTypes = new List<InternalType>() 
        {
            new InternalType("test") 
        };
    }

如果尝试在ExternalType之外实例化InternalType,则会出现编译器错误。但是您的家属将能够阅读该列表。