如何在 C# 中的 class 中正确隐藏助手(内部)classes
How to correctly hide helpers (inner) classes inside a class in C#
我在理解如何正确封装我的 class 时遇到问题。它是(或者应该是)一个不可变的class。
我正在使用 "helper class",我希望它不能从外面访问。
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
class protected
或 private
设置为 private
我会收到此错误:
Inconsistent accessibility: field type 'List'
is less accesible than field 'Frequencies.All'
如果我设置 class Frequency
和 List<Frequency> All
protected 并尝试创建一个 returns 和 List<Frequency>
类似的方法,我会得到同样的错误:
public List<Frequency> GetAll()
{
return All.Where(f => f.Octave.HasFlag(OctaveGroups.OneOctave)).ToList();
}
仅公开 .All
.OneOctave
和 .None
字段同时保持只读的正确方法是什么?
正确的做法是不隐藏。
您根本无法同时向外界隐藏和暴露class。
因此,如果您想声明一个 public 返回对象或对象集合的方法,您还必须指定相关对象的类型 public。
尝试向您的频率添加一个内部构造函数 class。这将允许您从 class 内部构造一个频率,但不允许在 class 之外构造它。由于无法在外部构建,class 之外的任何人都无法将新列表添加到您的列表中,因为它们是按频率输入的。
示例:
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,您将遇到编译器错误。但是,您的家属将能够阅读该列表。
当您计划让 public 方法返回 List<Frequency>
.
时,您不能期望隐藏 Frequency
现在,我的理解是您的问题是您需要 Frequencies
Frequency
中的可访问 属性 setters,但您不想公开它们到外面。这样做的方法是通过一个只暴露 getters 的接口:
public interface IFrequency
{
string Name { get; }
OctaveGroups Octave { get; }
}
现在,您将 Frequencies.Frequency
设为私有嵌套 class,并且仅公开 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
的消费者将只能看到 IFrequency
个没有 setter 暴露的实例,因此对外界是不可变的(当然不包括反射)。
我在理解如何正确封装我的 class 时遇到问题。它是(或者应该是)一个不可变的class。
我正在使用 "helper class",我希望它不能从外面访问。
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
class protected
或 private
设置为 private
我会收到此错误:
Inconsistent accessibility: field type 'List' is less accesible than field 'Frequencies.All'
如果我设置 class Frequency
和 List<Frequency> All
protected 并尝试创建一个 returns 和 List<Frequency>
类似的方法,我会得到同样的错误:
public List<Frequency> GetAll()
{
return All.Where(f => f.Octave.HasFlag(OctaveGroups.OneOctave)).ToList();
}
仅公开 .All
.OneOctave
和 .None
字段同时保持只读的正确方法是什么?
正确的做法是不隐藏。
您根本无法同时向外界隐藏和暴露class。
因此,如果您想声明一个 public 返回对象或对象集合的方法,您还必须指定相关对象的类型 public。
尝试向您的频率添加一个内部构造函数 class。这将允许您从 class 内部构造一个频率,但不允许在 class 之外构造它。由于无法在外部构建,class 之外的任何人都无法将新列表添加到您的列表中,因为它们是按频率输入的。
示例:
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,您将遇到编译器错误。但是,您的家属将能够阅读该列表。
当您计划让 public 方法返回 List<Frequency>
.
Frequency
现在,我的理解是您的问题是您需要 Frequencies
Frequency
中的可访问 属性 setters,但您不想公开它们到外面。这样做的方法是通过一个只暴露 getters 的接口:
public interface IFrequency
{
string Name { get; }
OctaveGroups Octave { get; }
}
现在,您将 Frequencies.Frequency
设为私有嵌套 class,并且仅公开 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
的消费者将只能看到 IFrequency
个没有 setter 暴露的实例,因此对外界是不可变的(当然不包括反射)。