我在理解如何正确封装我的课时遇到了问题。它是(或应该)一个不可改变的类。
我正在使用"帮助类"我希望它不能从外面访问。
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
课程protected
或private
,我会收到此错误:
可访问性不一致:字段类型&#39;列表&#39; 比现场频率更低,所以&#39;
如果我class Frequency
和List<Frequency> All
受到保护并尝试创建一个返回List<Frequency>
的方法,我会收到相同的错误:
public List<Frequency> GetAll()
{
return All.Where(f => f.Octave.HasFlag(OctaveGroups.OneOctave)).ToList();
}
如果只显示.All
.OneOctave
和.None
字段,同时保持只读字段的正确方法是什么?
答案 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,则会出现编译器错误。但是您的家属将能够阅读该列表。