How about new syntactical sugar for exception checking?
-
We get a shiny new "?" operator that takes
string result = null;
if (field != null)
{
result = field.Value;
}and converts this to
string result = field?.Value
So what about the case where we're handling a flaky API
string result = null;
try
{
result = DodgyApi.GetValue(); // may throw an exception
}
catch
{
result = null;
}What would you suggest we do for that? What about a headasplode (*) operator
string result = DodgyApi.GetValue*();
where
GetValue*
will silently swallow the exception thrown byGetValue
and returndefault
. Or am I setting a new standard for lazy, shameful programming here this hot, lazy afternoon?cheers Chris Maunder
How about a faux-extension method:
string result = DodgyApi.GetValue().OrDefault();
Then we can use it with LINQ as well to get rid of the ridiculousness of Single()/SingleOrDefault(), First()/FirstOrDefault() edit: After thinking about this a bit more, instead of syntactic sugar, isn't this one of the few raison d'être for the adapter pattern?
class DodgyApiAdapter: IDodgyApi { string GetValue() { try { string result = \_dodgyApiImpl.GetValue(); return result; } catch { return null; } } } string result = dodgyApiAdapterInst.GetValue();
I mean if you're doing the empty-catch-returns-null pattern for an API enough to want syntactic sugar, then isn't an adapter warranted?
-
We get a shiny new "?" operator that takes
string result = null;
if (field != null)
{
result = field.Value;
}and converts this to
string result = field?.Value
So what about the case where we're handling a flaky API
string result = null;
try
{
result = DodgyApi.GetValue(); // may throw an exception
}
catch
{
result = null;
}What would you suggest we do for that? What about a headasplode (*) operator
string result = DodgyApi.GetValue*();
where
GetValue*
will silently swallow the exception thrown byGetValue
and returndefault
. Or am I setting a new standard for lazy, shameful programming here this hot, lazy afternoon?cheers Chris Maunder
Headsplode does sound horribly like On Error Resume Next ... :~
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
-
I totally forgot about that! How about:
#pragma on error resume next
// ... code you wouldn't let your worst enemey near
Mwahaha
cheers Chris Maunder
-
We get a shiny new "?" operator that takes
string result = null;
if (field != null)
{
result = field.Value;
}and converts this to
string result = field?.Value
So what about the case where we're handling a flaky API
string result = null;
try
{
result = DodgyApi.GetValue(); // may throw an exception
}
catch
{
result = null;
}What would you suggest we do for that? What about a headasplode (*) operator
string result = DodgyApi.GetValue*();
where
GetValue*
will silently swallow the exception thrown byGetValue
and returndefault
. Or am I setting a new standard for lazy, shameful programming here this hot, lazy afternoon?cheers Chris Maunder
You could always write a helper method.
string GetString(int x)
{
throw new NotImplementedException();
}void Foo()
{
string s = NoEx.Run(() => GetString(100));
Console.WriteLine(s == null);
}class NoEx
{
public static T Run<T>(Func<T> method)
{
try
{
return method();
}
catch
{
return default(T);
}
}
}Not as clean as syntactic sugar, but fairly close :-)
Regards, Nish
Website: www.voidnish.com Blog: voidnish.wordpress.com
-
We get a shiny new "?" operator that takes
string result = null;
if (field != null)
{
result = field.Value;
}and converts this to
string result = field?.Value
So what about the case where we're handling a flaky API
string result = null;
try
{
result = DodgyApi.GetValue(); // may throw an exception
}
catch
{
result = null;
}What would you suggest we do for that? What about a headasplode (*) operator
string result = DodgyApi.GetValue*();
where
GetValue*
will silently swallow the exception thrown byGetValue
and returndefault
. Or am I setting a new standard for lazy, shameful programming here this hot, lazy afternoon?cheers Chris Maunder
As an idea I despite code that swallows exception without trace... Also null sometimes your best friend (but not default), so why to eliminate!?
Skipper: We'll fix it. Alex: Fix it? How you gonna fix this? Skipper: Grit, spit and a whole lotta duct tape.
-
Seems like an awful idea to me - I want code that silently swallows exceptions to be a pain to write. However, you could always add the suggestion to the Roslyn GitHub repo[^] for discussion. It doesn't seem half as mad as some of the other suggestions on there! :)
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
In this case, though, it's not really silently swallowing the exception. If the headasplode operator guarantees returning null on exceptions, then in using the operator your're explicitly expressing what you'd like to do if an exception occurs. It's more like exception handling shorthand than exception ignoring. :)
-
In this case, though, it's not really silently swallowing the exception. If the headasplode operator guarantees returning null on exceptions, then in using the operator your're explicitly expressing what you'd like to do if an exception occurs. It's more like exception handling shorthand than exception ignoring. :)
But with that operator, you've got to look closely at every method call to see whether or not it ignores exceptions. With the
try..catch
block, it's obvious what's happening. Also, how often do you really need to ignore every possible exception? Isn't it more likely that you'd want to ignore specific exception classes, and let unexpected exceptions propagate?
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
But with that operator, you've got to look closely at every method call to see whether or not it ignores exceptions. With the
try..catch
block, it's obvious what's happening. Also, how often do you really need to ignore every possible exception? Isn't it more likely that you'd want to ignore specific exception classes, and let unexpected exceptions propagate?
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
I agree that making things as obvious as possible is a good approach. How do you feel about the way Java handles this, where exceptions are part of the method signature, i.e.
int addSomeNumbers throws Abc { }
. And if you call a method that throws an exception, you have to either handle or rethrow (and add the throws clause to your method) if you want your code to compile. A lot of people seem to hate Java's checked exceptions, but if you're working on a big enough corporate code base, in which case there are probably at least a few lazy or marginally competent developers on the team, I can see the value in checked exceptions. -
I agree that making things as obvious as possible is a good approach. How do you feel about the way Java handles this, where exceptions are part of the method signature, i.e.
int addSomeNumbers throws Abc { }
. And if you call a method that throws an exception, you have to either handle or rethrow (and add the throws clause to your method) if you want your code to compile. A lot of people seem to hate Java's checked exceptions, but if you're working on a big enough corporate code base, in which case there are probably at least a few lazy or marginally competent developers on the team, I can see the value in checked exceptions.I can see the value, if they're done right. The temptation for lazy devs to add
throws Exception
is probably too high, though.
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
As an idea I despite code that swallows exception without trace... Also null sometimes your best friend (but not default), so why to eliminate!?
Skipper: We'll fix it. Alex: Fix it? How you gonna fix this? Skipper: Grit, spit and a whole lotta duct tape.
Kornfeld Eliyahu Peter wrote:
I despite code
Quick Nitpick: that should be 'I despise code'. Despite means 'without being affected by; in spite of.', where despise means 'feel contempt or a deep repugnance for.'
What do you get when you cross a joke with a rhetorical question? The metaphorical solid rear-end expulsions have impacted the metaphorical motorized bladed rotating air movement mechanism. Do questions with multiple question marks annoy you???
-
We get a shiny new "?" operator that takes
string result = null;
if (field != null)
{
result = field.Value;
}and converts this to
string result = field?.Value
So what about the case where we're handling a flaky API
string result = null;
try
{
result = DodgyApi.GetValue(); // may throw an exception
}
catch
{
result = null;
}What would you suggest we do for that? What about a headasplode (*) operator
string result = DodgyApi.GetValue*();
where
GetValue*
will silently swallow the exception thrown byGetValue
and returndefault
. Or am I setting a new standard for lazy, shameful programming here this hot, lazy afternoon?cheers Chris Maunder
This is a test, right?
Wrong is evil and must be defeated. - Jeff Ello
-
We get a shiny new "?" operator that takes
string result = null;
if (field != null)
{
result = field.Value;
}and converts this to
string result = field?.Value
So what about the case where we're handling a flaky API
string result = null;
try
{
result = DodgyApi.GetValue(); // may throw an exception
}
catch
{
result = null;
}What would you suggest we do for that? What about a headasplode (*) operator
string result = DodgyApi.GetValue*();
where
GetValue*
will silently swallow the exception thrown byGetValue
and returndefault
. Or am I setting a new standard for lazy, shameful programming here this hot, lazy afternoon?cheers Chris Maunder
To those of who still use pointers (even in .Net), using (*) might be a little confusing but I have an idea. How about using a construct similar to the for loop
// similar to...
for (int i = 0; i < limit; ++i) { ... }// you can have
NoThrow (var <out>; Func<T>; <result on throw>);// so your example becomes
string result;
NoThrow (result; dodgyApi.GetValue(); "I.M.Foo.Bar");if (Object.DividedByZero == true) { Universe.Implode(); } Meus ratio ex fortis machina. Simplicitatis de formae ac munus. -Foothill, 2016
-
We get a shiny new "?" operator that takes
string result = null;
if (field != null)
{
result = field.Value;
}and converts this to
string result = field?.Value
So what about the case where we're handling a flaky API
string result = null;
try
{
result = DodgyApi.GetValue(); // may throw an exception
}
catch
{
result = null;
}What would you suggest we do for that? What about a headasplode (*) operator
string result = DodgyApi.GetValue*();
where
GetValue*
will silently swallow the exception thrown byGetValue
and returndefault
. Or am I setting a new standard for lazy, shameful programming here this hot, lazy afternoon?cheers Chris Maunder
"new" doesn't mean what you think it does.
-
To those of who still use pointers (even in .Net), using (*) might be a little confusing but I have an idea. How about using a construct similar to the for loop
// similar to...
for (int i = 0; i < limit; ++i) { ... }// you can have
NoThrow (var <out>; Func<T>; <result on throw>);// so your example becomes
string result;
NoThrow (result; dodgyApi.GetValue(); "I.M.Foo.Bar");if (Object.DividedByZero == true) { Universe.Implode(); } Meus ratio ex fortis machina. Simplicitatis de formae ac munus. -Foothill, 2016
Too explicit. We need something that truly, deeply hides what's going on ;)
cheers Chris Maunder
-
Too explicit. We need something that truly, deeply hides what's going on ;)
cheers Chris Maunder
If that's the end goal, just use a carrot (^) instead of equals. That way anyone the uses managed C++ is really hosed. :laugh:
string result ^ dodgyApi.GetValue();
if (Object.DividedByZero == true) { Universe.Implode(); } Meus ratio ex fortis machina. Simplicitatis de formae ac munus. -Foothill, 2016
-
In this case, though, it's not really silently swallowing the exception. If the headasplode operator guarantees returning null on exceptions, then in using the operator your're explicitly expressing what you'd like to do if an exception occurs. It's more like exception handling shorthand than exception ignoring. :)
using System;
namespace InMemoriamMaunder
{
public enum DodgyResult
{
ResultNull,
ResultNonNull,
ResultError
}public static class Dodgy { public static DodgyResult RunDodgy(ref T param, Func dodgyFunc) { try { param = dodgyFunc(param); if (param == null) { return DodgyResult.ResultNull; } else { return DodgyResult.ResultOkay; } } catch (Exception) { return DodgyResult.ResultError; } } }
}
Tests:
private string SomeFuncError(string astring)
{
astring = null;
return astring.ToString();
}private string SomeFuncNull(string astring)
{
astring = null;
return astring;
}private string SomeFuncOkay(string astring)
{
astring = astring + astring;
return astring;
}string astring1 = "hello";
string astring2 = null;
string astring3 = "whatever";DodgyResult dr1 = Dodgy.RunDodgy(ref astring1, SomeFuncOkay);
DodgyResult dr2 = Dodgy.RunDodgy(ref astring2, SomeFuncNull);
DodgyResult dr3 = Dodgy.RunDodgy(ref astring3, SomeFuncError);Now, Chris, all you have left to do is boil this down to a single operator :)
«There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008
-
We get a shiny new "?" operator that takes
string result = null;
if (field != null)
{
result = field.Value;
}and converts this to
string result = field?.Value
So what about the case where we're handling a flaky API
string result = null;
try
{
result = DodgyApi.GetValue(); // may throw an exception
}
catch
{
result = null;
}What would you suggest we do for that? What about a headasplode (*) operator
string result = DodgyApi.GetValue*();
where
GetValue*
will silently swallow the exception thrown byGetValue
and returndefault
. Or am I setting a new standard for lazy, shameful programming here this hot, lazy afternoon?cheers Chris Maunder
Just something along the lines of a
TryGetValue<T>
Extension Method. :shrug: -
Just something along the lines of a
TryGetValue<T>
Extension Method. :shrug:You get my up-vote for the idea, but making the idea more general-purpose means, imho, not being able to use an Extension method with generics, since the 'this parameter of an Extension method cannot be declared 'ref, or 'out. How about this (based on the code example in my previous reply to this thread)
using System;
namespace InMemoriamMaunder
{
public enum DodgyResult
{
ResultNull,
ResultOkay,
ResultError
}public static class DodgyUtilities { public static DodgyResult TryGetValueFromDodgy<T1,T2>(T1 t1, ref T2 t2, Func<T1,T2> func) { try { t2 = func(t1); if (t2 == null) { return DodgyResult.ResultNull; } else { return DodgyResult.ResultOkay; } } catch (Exception) { return DodgyResult.ResultError; } } }
}
«There is a spectrum, from "clearly desirable behaviour," to "possibly dodgy behavior that still makes some sense," to "clearly undesirable behavior." We try to make the latter into warnings or, better, errors. But stuff that is in the middle category you don’t want to restrict unless there is a clear way to work around it.» Eric Lippert, May 14, 2008
-
On the "?" operator - I will strive NEVER to use that. On the head-asplode operator - Shouldn't that be
string result = DodgyApi.GetValue?*.();
And why aren't you working on my latest feature request?*.() And please don't say you simply haven't GOTTEN around to it yet.
".45 ACP - because shooting twice is just silly" - JSOP, 2010
-----
You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010
-----
When you pry the gun from my cold dead hands, be careful - the barrel will be very hot. - JSOP, 2013John Simmons / outlaw programmer wrote:
On the "?" operator - I will strive NEVER to use that.
Why? :confused:
Read my (free) ebook Object-Oriented Programming in C# Succinctly. Visit my blog at Sander's bits - Writing the code you need. Or read my articles here on CodeProject.
Simplicity is prerequisite for reliability. — Edsger W. Dijkstra
Regards, Sander
-
We get a shiny new "?" operator that takes
string result = null;
if (field != null)
{
result = field.Value;
}and converts this to
string result = field?.Value
So what about the case where we're handling a flaky API
string result = null;
try
{
result = DodgyApi.GetValue(); // may throw an exception
}
catch
{
result = null;
}What would you suggest we do for that? What about a headasplode (*) operator
string result = DodgyApi.GetValue*();
where
GetValue*
will silently swallow the exception thrown byGetValue
and returndefault
. Or am I setting a new standard for lazy, shameful programming here this hot, lazy afternoon?cheers Chris Maunder
No programming questions in the Lounge! ;P
Chris Maunder wrote:
Or am I setting a new standard for lazy, shameful programming here this hot, lazy afternoon?
Surely you jest! It's only 117° today, but we're supposed to warm up for the weekend.
Will Rogers never met me.