in-line 'try' statement in C# possible?

12,745

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.

Share:
12,745

Related videos on Youtube

Stan
Author by

Stan

Updated on June 04, 2022

Comments

  • Stan
    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 use try and also catch 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
      Konrad Rudolph about 11 years
      Nah. You’re approaching this the wrong way. Fix your error instead of trying to silence it!
    • Stan
      Stan about 11 years
      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
      Konrad Rudolph about 11 years
      @Steve No, you can fix it.
  • Stan
    Stan about 11 years
    I think that this exception is pretty much out of control, is it not? (Edited my post)
  • Darin Dimitrov
    Darin Dimitrov about 11 years
    Of 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
    Joachim Isaksson about 11 years
    Well, the FirstOrDefault returns a CultureInfo, but you're assigning it to a string. Like the idea though.
  • Darin Dimitrov
    Darin Dimitrov about 11 years
    @JoachimIsaksson, good point, let me fix that. Answer updated.
  • CodesInChaos
    CodesInChaos about 11 years
    if this one is too slow, you can turn it into a Dictionary<string, CultureInfo>
  • Dan Atkinson
    Dan Atkinson about 7 years
    I 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
    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
    Dan Atkinson about 7 years
    I 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
    Murilo Maciel Curti over 2 years
    Inspired on @Andy class