C#仅具有单个属性的新类:从基派生还是封装到新类?
我试图描述:)这是编程风格的问题,而不是编码本身的问题 假设我们有: A:C#仅具有单个属性的新类:从基派生还是封装到新类?,c#,class,coding-style,derived-class,C#,Class,Coding Style,Derived Class,我试图描述:)这是编程风格的问题,而不是编码本身的问题 假设我们有: A: 公共类MyDict{ 公共词典; //对“dict”进行自定义序列化 公共无效保存文件(…); //自定义“dict”反序列化 公共void LoadFromFile(…); } B: 公共类MyDict:字典 { } 在编程风格方面,哪个选项更好? B类:将从外部反序列化 主要问题是:创建一个新类(只有一个属性,比如opta:)还是创建一个新的派生类,比如optb:? 除了添加/删除和反序列化到流之外,我不需要任
公共类MyDict{
公共词典;
//对“dict”进行自定义序列化
公共无效保存文件(…);
//自定义“dict”反序列化
公共void LoadFromFile(…);
}
B:
公共类MyDict:字典
{
}
在编程风格方面,哪个选项更好?
B类:将从外部反序列化
主要问题是:创建一个新类(只有一个属性,比如opta:)还是创建一个新的派生类,比如optb:?
除了添加/删除和反序列化到流之外,我不需要任何其他数据处理
提前谢谢 为什么需要创建一个新类?或者更确切地说,为什么它必须是一个能够加载和保存自身的类?为什么不在其他地方采用以下方法:
public void SaveDictionary(Dictionary<int, string> dictionary, string fie)
public Dictionary<int, string> LoadDictionary(string file)
公共void保存字典(字典字典,字符串fie)
公共字典加载字典(字符串文件)
我会选择选项B。如果我想在幕后使用字典(即,使其私有/受保护),并且只在我的新类中公开字典中的有限功能,我只会使用选项A
如果您提供了字典的所有功能,然后是一些功能,那么显而易见的解决方案是继承字典(a la选项B)我为另一个问题编写的答案: 当您要“复制”/公开 基类的API,则使用继承。 当你只想“复制” 功能,使用委派 举个例子:你想 从列表中创建一个堆栈。堆栈 只有pop、push和peek。你 鉴于此,我们不应该使用继承 你不想向后推,向前推, removeAt等-一种功能 一叠 另一方面,这两种方法似乎都不是最“适合”你的困境。您可能会创建一个帮助器类来完成整个序列化工作,例如:
class DictionarySerializationHelper
{
public static void Serialize(Dictionary<int, String> d, File f){
//...
}
public static Dictionary<int, String> Deserialize(File f)
{
//...
}
}
类字典SerializationHelper
{
公共静态void序列化(字典d,文件f){
//...
}
公共静态字典反序列化(文件f)
{
//...
}
}
这种方法可能很好,因为您还可以泛化静态方法以允许任何字典专门化。您可以始终使用两种扩展方法
public static class DictionaryExtensions
{
public static void Save<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, string fileName)
{
// TODO: save logic
}
public static void Load<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, string fileName)
{
// TODO: load logic
}
}
公共静态类字典扩展
{
公共静态void保存(此字典,字符串文件名)
{
//TODO:保存逻辑
}
公共静态无效加载(此字典,字符串文件名)
{
//TODO:加载逻辑
}
}
或者,如果您只使用词典
公共静态类字典扩展
{
公共静态void保存(此字典,字符串文件名)
{
//TODO:保存逻辑
}
公共静态无效加载(此字典,字符串文件名)
{
//TODO:加载逻辑
}
}
问题的最佳解决方案取决于用例。您没有告诉我们在您的项目中如何使用该类。如果您想拥有一个非常普通的字典,并且只想添加用于加载和保存的方法,那么您应该看看扩展方法:
public static class DictionaryExtensions
{
public static void Save(this Dictionary<int,string> yourDict, ...) {...}
public static void Load(this Dictionary<int,string> yourdict, ...) {...}
}
公共静态类字典扩展
{
公共静态无效保存(此字典yourDict…{…}
公共静态无效负载(此字典yourdict…{…}
}
现在,您可以像这样保存一个实例:
Dictionary<int,string> dict = ....;
dict.Save(...);
Dictionary dict=。。。。;
dict.Save(…);
我的2美分:
在示例A中,当我想向类的使用者隐藏代码使用字典的事实时,我会使用这种样式
在示例B中,当我不介意消费者知道我在使用字典时,我会这样做
因此,根据场景的不同,我可能可以选择一种编码风格/策略&我认为这种想法与类是否需要序列化无关
我很想听到一些关于这一思路的评论
HTH.您可以创建自己的类,该类实现了
IDictionary
和IXmlSerializable
(或者,无论哪个序列化接口需要您想要的功能,您可能都必须创建自己的)。我想我记得在某个地方读到过,出于某种原因,最好实现IDictionary
接口,而不是从Dictionary
继承
编辑:是我问的关于从Dictionary类继承的问题。请参见此处的答案,了解为什么这是一个坏主意。+1您可能能够概括并使用
SaveDictionary(IDictionary dictionary,string file)
,并且您将拥有一个适用于多种字典类型的实现。嘿,您是对的。我想我对OOP封装命令做得太过分了,我试图将所有内容封装到类中……我认为这两个选项(OOP和过程)在这里都是完全有效的。问题在于如何使用这个类,以及您对哪个选项更满意。@TJMonk15--我不确定我是否会将其称为“过程性”解决方案。我认为@Jon只是说,将序列化分离到它自己的类中可能更好。毕竟,为什么词典会或应该知道或关心它是如何持久化的呢。这似乎不是字典的功能,而是序列化程序。@TJMonk15:我同意tvanfosson的观点。如果他以后想以不同的格式保存词典
,该怎么办?“面向对象”并不意味着“把所有的东西都塞进一个类”。如果你这样做了,关注点的封装或分离在哪里?制作扩展方法
public static class DictionaryExtensions
{
public static void Save(this Dictionary<int, string> dictionary, string fileName)
{
// TODO: save logic
}
public static void Load(this Dictionary<int, string> dictionary, string fileName)
{
// TODO: load logic
}
}
public static class DictionaryExtensions
{
public static void Save(this Dictionary<int,string> yourDict, ...) {...}
public static void Load(this Dictionary<int,string> yourdict, ...) {...}
}
Dictionary<int,string> dict = ....;
dict.Save(...);