If it was hard to write, it should be hard to understand, that’s an unwritten rule-that-rules-them-all of programming. You absolutely love to apply syntactical stunts to impress our coworkers, especially if you do C# and they don’t, don’t you?
One of those stunts (at least from C/AL) perspective is a C-language type common feature known as conditional operator. It allows you to write this:
a = b ? c : d;
when you would normally (in C/AL, for example) get more eloquent:
if (b == true) { a = c; } else { a = d; }
This (b == true) could have been replaced with just (b), but I put it there for clarity.
But! (There is always a “but”!)
Even though it may not be obvious, there is a catch 22 which often doesn’t cause any issues at all, but sometimes can break everything. It’s the fact that the whole expression involving the conditional operator, just like any other expression, has a type. It means one type.
While you may think this is a nice syntactical stunt:
public object ConvertBoxedIntToProperIntType(object a) { return Convert.ToInt64(a) > Int32.MaxValue ? Convert.ToInt64(a) : Convert.ToInt32(a); }
This won’t achieve anything at all, and the boxed type of the returned value will always be Int64, simply because the expression type involved is higher of the two types – and that’s Int64.
If you are one of the types that have their opinion and don’t want to be confused by facts, take a look at this little fiddle: https://dotnetfiddle.net/6KzSpb
I’ve just stumbled upon this problem when deserializing Dictionary<string,object> from JSON, where any integer number would just be deserialized as Int64, so I wrote my nice JsonConverter class that attempted to be too smart by applying conditional operator to the return value:
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var jsonValue = serializer.Deserialize<JValue>(reader); if (jsonValue.Type == JTokenType.Integer) { return jsonValue.Value<Int64>() > Int32.MaxValue ? jsonValue.Value<Int64>() : jsonValue.Value<Int32>(); } return jsonValue.Value;}
Alas, it didn’t work, so I had to fix it by changing it to less elegant (or geeky) into more direct, totally obvious:
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var jsonValue = serializer.Deserialize<JValue>(reader); if (jsonValue.Type == JTokenType.Integer) { if (jsonValue.Value<Int64>() > Int32.MaxValue) { return jsonValue.Value<Int64>(); } return jsonValue.Value<Int32>(); } return jsonValue.Value; }
And – so help me God – I swear if I didn’t write it myself, and I got by that code in a review for example, I’d routinely change this into my original, immediately causing a bug.
And yes – sorry for an off-topic post, but what’s really off-topic nowadays, when it comes to NAV?
Read this post at its original location at http://vjeko.com/blog/off-topic-a-c-lesson-learned-about-conditional-operators, or visit the original blog at http://vjeko.com. 5e33c5f6cb90c441bd1f23d5b9eeca34
The post Off-topic: A C# lesson learned about conditional operators appeared first on Vjeko.com.