Reputation: 17196
For a fun project I'm trying to implement the BitTorrent spec, and right now I'm working on the BEncoding portion of it.
The encoding basically can encode from int/string/dictionary -> string for transmission. I've got all of the different encodings written/tested/working as overloaded Encode(...) methods and I've got the individual decode methods written/tested/working as DecodeString(...), DecodeInt(...) etc.
I can't figure out a way to have 1 Decode method for all decodings, in order to keep the API for the encoding/decoding as clean as possible (2 public methods, tops, for the time being).
Note that I have a method that can get the type of result that the decoded string will have.
Client code, right now would have to look something like this every time they want to decode a message:
string s = ...; // Encoded string
Type t = Encoder.GetDecodedType(s);
if (t == typeof(int))
process(Encoder.DecodeInt(s));
else if (t == typeof(string))
process(Encoder.DecodeString(s));
else if (t == typeof(Dictionary<string, string>))
process(Encoder.DecodeStringDictionary(s));
else if (t == typeof(Dictionary<string, int>))
process(Encoder.DecodeIntDictionary(s)):
and I'd like to be able to clean that up to be more like:
string s = ...; // Encoded string
process(Encoder.Decode(s));
where, in both cases the process(...) would likely be overloaded functions at the client end taking the 4 types of decoded values.
Upvotes: 1
Views: 141
Reputation: 47749
If you are writing a library/framework ... this will be the most invaluable resource in your endeavor :-) I have the hardcopy and read it cover to cover:
Design Guidelines for Developing Class Libraries from Microsoft
Upvotes: 1
Reputation: 66573
You could let the DLR do this for you.
public static void Process(int i) { ... }
public static void Process(string s) { ... }
public static void Process(Dictionary<string, string> dic) { ... }
public static void Process(Dictionary<string, int> dic) { ... }
[...]
public dynamic Decode(string input) // or 'object' if you prefer
{
var t = GetDecodedType(input);
if (t == typeof(int))
return DecodeInt(input);
else if (t == ...)
// ...
}
[...]
string s = ...; // Encoded string
Process(Encoder.Decode(s)); // if you used 'dynamic' above
Process((dynamic)Encoder.Decode(s)); // if you used 'object' above
Upvotes: 3
Reputation: 24713
I'm confused. why not simply perform the GetDecodedType logic in the public Decode method and determine the type and then make the varying calls once determined?
Upvotes: 0
Reputation: 24316
I would say that you should follow the Liskov Substitution Principle here and create a method for each data type. That way you don't keep adding to the misery of utilizing typeof when you start passing custom objects. After reading over your question again, you already know the type being passed to it, so that further supports the need to remove the typeof operation
Upvotes: 0