Here is a very simple functionality example, to make the discussion easy. Suppose, I am logging some abstract objects' content in a flat log. If an object's json representation contains property called EntityID with a GUID, I'd like to record it as a separate data element, if not - no matter, we still store the json but without the additional metadata.
So, I'll need a method which would return an ID if we are able to extract it or null if not. My instincts tell me to code it like this:
private Guid? ParseSyncTableUniqueIdFromContent(string content)
{
try
{
object contentObject = JsonConvert.DeserializeObject(content);
if (contentObject is JObject typedContentObject)
{
return Guid.Parse(typedContentObject.Value<string>("EntityID"));
}
}
catch
{
// well, ok then
}
return null;
}
The code in try section might fail in a number of ways: content might be null, it might be not null but cause some other exceptions inside DeserializeObject, and then even if we manage to deserialize, the object might not contain the property and even if it does it might not be parseable into a GUID. Since I don't care which problem would prevent me from getting to the value, I simply catch anything that might happen and move on.
An alternative would be to introduce several validations which would just return a null immediately.
if (string.IsNullOrEmpty(content))
return null;
etc.
My sense of aesthetics and my habits say that a catch-all in this case is acceptable. But now let's remember that we are inside the managed .Net code and that makes me wonder. Does the exception mechanism become a resourse drain, then? How significant is the overhead on handling the exception in .Net?
The reason I ask is actually this. This particular function is quite often called within a large, high-load application, which employs an (in my opinion not well justified) method of catching all of the exceptions in the FirstChanceException event and tracking them all in Application Insights (I do think it's too blunt, but that's a different story for a different time, I guess). But it makes me think of such use of exceptions in .Net - is it too "expensive" even without such detailed logging taken into account? Is it (much) more efficient to write validation checks? (IMO, would suck if it is like that, but I feel like I need to know)