- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
byte[frist]
Admin
While this may not be the "ideal" solution in .NET it works and no doubt works for all the required types that the library needs to convert. Using overriding or generics would have just added to the spaghetti-ness of the code and not really delivered any real benefits. As is the code is clear in meaning and intent to any competent programmer. The programmer even used a case statement and not a chain of If Else!
And as for the setting the returning of "value" while not in this code there are situations where that might be advantageous to do so (if multiple actions need to be preformed on the value before return) , and therefore might have been just an adopted coding style for whatever individual or team developed the lib.
The real WTF with this is there is no real WTF...
Admin
It also doesn't help that if passed something whose runtime type isn't one it recognizes -- say, an IQueryable instead of a list or a NameValueCollection instead of a dict, or even a list/dict with different type parameters, it doesn't even throw to indicate something bad happened. Instead, as far as the serialized data is concerned, whatever you passed in silently ceases to exist!
Admin
There is no doubt that using method overloads would be the right way here. There is no spaghetti-ness involved in doing so.
Unless you and your coworkers are all masochists and prefer silent runtime failures over compile-time errors.
Admin
I'm with Poxun
9 classes (which means 9 source files), each containing one method with one line of code. that's too dogmatic for me
Admin
TRWTF is that it sets 'value' in a static procedure, thus setting itself up for a multi-threaded failure
Admin
It's a local variable. Each invocation of this method will have its own copy, whether static or not. Unless I'm very much mistaken.
Admin
I agree. Look, polymorphism and generics are amazing tools for a lot of jobs. I'm not even disagreeing that it would be a great tool here. The lack of using it isn't a facepalming WTF that would make me take a deep sigh and reconsider my job options, as a lot of other WTFs on this site are. But, using a switch-case for a simple problem like converting an object with, presumably, only a handful of possible types for the properties, isn't a huge WTF. Perhaps the reflection could have been done without converting a type to a string. There's a little bit of verbosity in the code that could be simplified a little, but overall, if I encountered this code, I'd shrug my shoulders and move on.
The only thing that would make me take some effort to refactor this code is if it were performing poorly. There's a distinct possibility that using generics in compiled code is faster than using reflection to convert a type to a string and switch-casing it, and anytime you want to convert a .NET object to a binary file, you typically want to optimize that as much as you can.
Admin
"Despite being a .NET library, it uses PLists as its configuration format- despite .NET offering a perfectly good in-built format."
Holy redundant Batman
Admin
Dictionary< Type, Func<Obj, byte[]> translateLibrary = { ... } Func<Obj, byte[]> doTranslation = (x) => translateLibraryx.GetType();
...
Admin
The value assignment may have come from some old scenario or boiler plate that was never rescinded when it's need turned out absent.
Admin
The value assignment is because the developer was used to stepping through his code while debugging.
Admin
But it's SOLID!
Admin
Using polymorphism would, if I'm not mistaken, require being able to modify the types. I haven't used .Net for years, but is that possible? Lacking that this is not a bad way to go about it. Perhaps better would be setting up a handler that maps from a type object to a method, but that would probably be a PITA for little gain. As dpm said, having an assignment lets you look at the value in the debugger.
Admin
Most of the plist files that ship with
Mac OS XmacOS are in the binary format. You can convert them back to human-readable XML with:plutil -convert xml1 file.plist
(TRWTF: "xml1" instead of "xml")
Admin
I'm fascinated. What is this "human-readable XML" whereof you speak?
Then again, coercing the .NET type system into a subset of string identifiers simply so that you can apply a PList mechanism (I neither know nor care what PLists are) via a switch statement is ... sub-optimal. I don't actually care whether it's an if-else chain, a switch, a pattern match, or a dictionary. It's sub-optimal in a back-brained sort of way.
What happens, for instance, if the .NET crew change the way these things are named, such that "List`2" is reborn as "BlatWarblerSiriusMajor"? Possibly the .NET standards forbid this, but I doubt it. So far as I am aware, the only two reasons for ToString() to exist where types are concerned are (a) all objects have to support ToString() and more importantly (b) it's handy for tools like debuggers.
BUT FOR NOTHING ELSE.
Admin
Polymorphism wouldn't be the way to go, especially seeing as those are framework classes.
However - initialising a Dictionary<Type, Func<object, byte[]>> would be. The code for the method would then be:
Func<object, byte[]> function; if (obj != null && _parseActions.TryGetValue(obj.GetType(), out function)) { return function(obj); } return new byte[0];
And the dictionary initialization would be pretty simple:
private static Dictionary<Type, Func<object, byte[]>> _parseActions = new Dictionary<Type, Func<object, byte[]>> { { typeof(Dictionary<string, object>), obj => writeBinaryDictionary((Dictionary<string, object>)obj) }, { typeof(List<object>), obj => composeBinaryArray((List<object>)obj) }, ... snip ... }
I take strong exception to your statement that 'there is no real WTF here'. Because that code could be much more readable & succinct.
Admin
Nope, not really a WTF in the value assignment. Pulling out for less returns would be an option for those of us who like their things to fall off at the end, but then you'd just have to break all over the place (because years and years on, the C offspring still haven't dared to have a "fallthrough" keyword).
Admin
No WTFs here at all, and a lot of the comments are making assumptions or are plain wrong.
e.g. if the caller looks like this
object obj =GetSomeData(); byte[] result = composeBinary(obj);
Q: what does the generic method look like? A: composeBinary<object>(...) - not much help there
The only minor issue is "value = ... and return value" - however for debugging purposes this can be preferable, and I've done it before.
So TRWTF is the original submitter not knowing this isn't a WTF, and DailyWTF for posting it.
Admin
Well, as we learned last week, both Cases and If/Then/Else are verboten nowadays. They should have been using Ternary's.
Admin
Personally I would prefer
Func< Type, Func<Obj, byte[]>> translateLibrary = { ... }
over
Dictionary< Type, Func<Obj, byte[]>> translateLibrary = { ... }
because that could also handle generic types (including things like List<List<List<List<String>>>>)
Admin
Yes, praise the almighty ternary!
Admin
"TRWTF is the original submitter not knowing this isn't a WTF, and DailyWTF for posting it"
A fkn +!
Although I still <3 you, TheDailyWTF. :)