in-line 'try' statement in C# possible?
Solution 1
First off, it is always better to figure out how to avoid the exception in the first place. Concentrate on that first. There is some reason why that exception is being thrown, and if you can determine what it is, then don't do that.
To actually answer your question: there is no out-of-the-box "eat all the exceptions in this expression" mechanism, but building your own is straightforward:
static T EatExceptions(Func<T> func)
{
try { return func(); } catch { }
return default(T);
}
...
clientLanguage = (filterContext.HttpContext.Request.UserLanguages != null) ?
EatExceptions(() => new CultureInfo(filterContext.HttpContext.Request.UserLanguages[0]).TwoLetterISOLanguageName) :
null; }
If someone tried to pull shenanigans like that in code I was reviewing then I would... well let's just say that the change would not get checked in. Eating exceptions like this is a very bad idea 99% of the time. Again: figure out what you are doing wrong and stop doing it. Don't do something wrong and then handle the failure.
Solution 2
Have you tried getting rid of the try/catch
statement completely?
string clientLanguage = null;
var userLanguages = filterContext.HttpContext.Request.UserLanguages;
if (userLanguages != null && userLanguages.Length > 0)
{
var culture = CultureInfo
.GetCultures(CultureTypes.AllCultures)
.FirstOrDefault(
x => string.Equals(
x.Name,
userLanguages[0].Name,
StringComparison.OrdinalIgnoreCase
)
);
if (culture != null)
{
clientLanguage = culture.TwoLetterISOLanguageName;
}
}
Use try/catch only for handling exceptions that are out of your control. As their name suggests exceptions should be used for handling exceptional cases.
In this case you are doing standard parsing so it is much better to do defensive programming instead of trying, throwing, catching, ...
Solution 3
_.Try(() => __YourStatementHere__ );
Using a little helper class like this:
/// <summary>
/// Other utility functions.
/// </summary>
public static class _ {
/// <summary>
/// Tries to execute the given action. If it fails, nothing happens.
/// </summary>
public static void Try(Action action) {
try {
action();
}
catch {
}
}
}
I know, this solution is not optimal either, but up to now the most concise one I could find.
Solution 4
What you did is the right way to do it. You stated, why you cannot get rid of the exception (and I assume this is the case). So you have to handle it. Alas, C# does not have a try-catch as an expression (not sure how that would work - the catch "clause" would need to return a value).
Alternatively you can build a little helper function that takes a Func<T>
, invokes it and passes through the value to the caller. If an exception occurres it returns (for example) default(T)
. That takes away a lot of the clutter and is reusable.
Solution 5
First try to avoid the exception. Just because the string comes from a source you don't control, doesn't mean you can't validate it.
If you can't avoid it, you should catch the specific exception you expect and encapsulate that logic in a method. Don't catch all exceptions.
For example:
public static CultureInfo TryGetCultureByName(string name)
{
try
{
return new CultureInfo(name);
}
catch(CultureNotFoundException)//Only catching CultureNotFoundException
{
return null;
}
}
That way, if you later discover a better way to handle this specific error, you can easily replace it.
For example you could create a Dictionary<string, CultureInfo>
, fill it from CultureInfo.GetCultures()
and use TryGetValue
to look up a culture without ever throwing an exception.
Related videos on Youtube
Stan
Updated on June 04, 2022Comments
-
Stan almost 2 years
Is it possible to somehow invoke inline
try
statement in C#?I'm detecting languages for my website and sometimes, when language is something like
en-GR
on client side for some reason .NET throws exception. So I need to usetry
and alsocatch
even though I'm not really catching anything.It just seems as a total overkill in this situation.
// Set allowed languages string[] allowedLanguages = { "en", "fr", "ru" }; // Get all possible values var routeLanguage = (filterContext.RouteData.Values["lang"] != null && allowedLanguages.Contains(filterContext.RouteData.Values["lang"].ToString())) ? filterContext.RouteData.Values["lang"].ToString() : null; var cookieLanguage = (filterContext.HttpContext.Request.Cookies["lang"] != null && allowedLanguages.Contains(filterContext.HttpContext.Request.Cookies["lang"].Value)) ? filterContext.HttpContext.Request.Cookies["lang"].Value : null; string clientLanguage = null; try { clientLanguage = (filterContext.HttpContext.Request.UserLanguages != null) ? new CultureInfo(filterContext.HttpContext.Request.UserLanguages[0]).TwoLetterISOLanguageName : null; // Exception sometimes without `try` } catch (Exception) { }
Edit
Exception is not something I can fix since I have no control over what user has in his culture info. .NET just sees en-FR as invalid one.
-
Konrad Rudolph about 11 yearsNah. You’re approaching this the wrong way. Fix your error instead of trying to silence it!
-
Stan about 11 yearsException is not something I can fix since I have no control over what user has in his culture info. .NET just sees
en-FR
as invalid one. -
Konrad Rudolph about 11 years@Steve No, you can fix it.
-
-
Stan about 11 yearsI think that this exception is pretty much out of control, is it not? (Edited my post)
-
Darin Dimitrov about 11 yearsOf course that it is not out of control. Look at my code. I am controlling it. The OP was trying to pass the
TwoLetterISOLanguageName
directly to the CultureInfo constructor. Obviously this could throw an exception if the client has passed some invalid language. In my example I am attempting to find the corresponding CultureInfo from the list of all possible values which cannot throw. -
Joachim Isaksson about 11 yearsWell, the FirstOrDefault returns a CultureInfo, but you're assigning it to a string. Like the idea though.
-
Darin Dimitrov about 11 years@JoachimIsaksson, good point, let me fix that. Answer updated.
-
CodesInChaos about 11 yearsif this one is too slow, you can turn it into a
Dictionary<string, CultureInfo>
-
Dan Atkinson about 7 yearsI completely agree with the fact that you should always avoid the exception as it's not very performant. I had a case where I wanted my application to attempt doing something and if it failed, it didn't really matter as it was a superfluous.
-
Eric Lippert about 7 years@DanAtkinson: The issue is not that exceptions are slow. Exceptions are slow in comparison to, say, addition, but that's because addition is insanely fast. You could throw thousands of exceptions a second and not worry about the perf implications. The issue is that exceptions are supposed to be exceptional. A throw is a non local goto; it is hard to imagine a more potentially confusing and damaging control flow than that. So it should be limited to only rare, carefully analyzed cases.
-
Dan Atkinson about 7 yearsI of course agree with what you're saying. This answer is probably a sticking plaster on a wider problem, and 'covering up' any attempt to deal with it is counter-intuitive. :-)
-
Murilo Maciel Curti over 2 yearsInspired on @Andy class