views:

107

answers:

7

I've tried to be descriptive :) It's rather programming-style problem than coding problem in itself.

Let's suppose we have :

A:

public class MyDict {
     public Dictionary<int,string> dict;
     // do custom-serialization of "dict"
     public void SaveToFile(...);
     // customized deserialization of "dict"
     public void LoadFromFile(...);
} 

B:

public class MyDict : Dictionary<int,string>
{

}

Which option would be better in the matter of programming style ? class B: is to be de/serialized externally.

Main problem is : is it better to create new class (which would have only one property - like opt A:) or to create a new class derived - like opt B: ? I don't want any other data processing than adding/removing and de/serializing to stream.

Thanks in advance!

+6  A: 

Why do you need to create a new class at all? Or rather, why does it have to be a class which can load and save itself? Why not have methods elsewhere of:

public void SaveDictionary(Dictionary<int, string> dictionary, string fie)

public Dictionary<int, string> LoadDictionary(string file)
Jon Skeet
+1 you might be able to generalize and use `SaveDictionary<TKey,TValue>( IDictionary<TKey,TValue> dictionary, string file )` and you'd have an implementation that would work for lots of Dictionary types.
tvanfosson
@Jon Skeet: why not?
Luiscencio
Heh, you're right.I suppose I got myself too far into OOP encapsulation commandment, and I tried to encapsulate everything into classes...
Gobol
I think both options (OOP vs. procedural) are perfectly valid here. It just comes down to how this class is going to be used, and which choice you feel more comfortable with.
TJMonk15
@TJMonk15 -- I'm not sure that I would call this a "procedural" solution. I think @Jon's just saying that it might be better to separate out serialization into it's own class. After all, why would or should a Dictionary know or care how it is persisted. That doesn't seem to be a function of a dictionary, but rather a serializer.
tvanfosson
@TJMonk15: I agree with tvanfosson. What if he later wants to save the `Dictionary` in a different format? "Object-oriented" doesn't mean "cram everythiing into one class." If you do that, where's the encapsulation or separation of concerns?
kyoryu
@Luiscencio: The only custom behaviour we know about so far is serialization - which IMO *interacts* with the state of the dictionary rather than being *part* of the state itself. That's why I don't see any benefit in putting the two together.
Jon Skeet
+1  A: 

I would go for option B. I would only use Option A if I wanted to use the Dictionary behind the scenes (ie. make it private/protected) and only expose a limited amount of functionality from the Dictionary in my new class.

If you are offering all of the functionality if the Dictionary and then some, the obvious solution would be inheriting from Dictionary (a la Option B)

TJMonk15
+1  A: 

From an answer I wrote for another question:

When you want to "copy"/Expose the base class' API, you use inheritance. When you only want to "copy" functionality, use delegation.

One example of this: You want to create a Stack out of a List. Stack only has pop, push and peek. You shouldn't use inheritance given that you don't want push_back, push_front, removeAt, et al.-kind of functionality in a Stack.

On the other hand, neither approach seems to be the most "suitable" for your dilemma. You could probably create a helper class that does the whole serialization work such as:

class DictionarySerializationHelper
{
    public static void Serialize(Dictionary<int, String> d, File f){
    //...
    }
    public static Dictionary<int, String> Deserialize(File f)
    {
    //...
    }
}

This approach might be great because you could also generalize the static methods to allow any Dictionary specialization.

Anzurio
I originally made my sample methods static too, but there could be cases where you want instance methods - you may even want an IDictionaryStorage interface, so that it can serialize to/from different formats interchangably. It all depends on the exact requirements.
Jon Skeet
A: 

You could always use a couple of Extension Methods

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
    }
}

Or, if you'll only be using a Dictionary<int, string>

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
    }
}
fre0n
Making extension methods for a generic IDictionary<K, V> gives you the most flexibility. Anything that implements the same interface can serialized and deserialized with your new extension methods.
Frode N. Rosand
@Frode: Extension methods don't give you the flexibility of specifying the storage format elsewhere; if you specify a storage interface with Load/Save methods you can implement that depending on the requirements, and then inject that storage interface implementation into anything that needs it.
Jon Skeet
A: 

Best solution for you problem depends on the use case. You don't tell us how the class is used in your project. If you want to have a quite normal Dictionary and just want to add methods for loading and saving, you should have a look at extension methods:

  public static class DictionaryExtensions
  {
        public static void Save(this Dictionary<int,string> yourDict, ...) {...}
        public static void Load(this Dictionary<int,string> yourdict, ...) {...}
  }

Now you can save an instance like this:

Dictionary<int,string> dict = ....;
dict.Save(...);
Achim
A: 

My 2 cents:

In sample A - I would use this style when I want to hide the fact that my code uses the Dictionary from the consumer of my class.

In Sample B - I would do this when I don't mind the consumer knowing that I am using Dictionary

So depending on the scenario, I might be able to choose one style/strategy for coding & I think this thinking is irrespective of the fact that the class needs to be serialized or not...

Would love to hear some comments on this line of thinking.

HTH.

Sunny
A: 

You could make your own class that implements both IDictionary<TKey, TValue> and IXmlSerializable (or whichever serialization interface requires the functionality you want, you might have to create your own). I think I remember reading somewhere that it was preferable to implement the IDictionary<TKey, TValue> interface rather than inheriting from Dictionary<TKey, TValue>, for some reason.

Edit: C# inherit from Dictionary, iterate over KeyValuePairs is a question I asked about inheriting from the Dictionary class. See the answers there for why this is a bad idea.

Sarah Vessels