Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
直列式';试试';用C#可能吗?_C#_Exception_Exception Handling_Try Catch - Fatal编程技术网

直列式';试试';用C#可能吗?

直列式';试试';用C#可能吗?,c#,exception,exception-handling,try-catch,C#,Exception,Exception Handling,Try Catch,是否可以以某种方式调用C#中的内联try语句 我正在为我的网站检测语言,有时,由于某种原因,客户端的语言类似于en GR。NET抛出异常。所以我需要使用try和catch,即使我没有真正捕捉到任何东西 在这种情况下,这似乎是一种完全的矫枉过正 // Set allowed languages string[] allowedLanguages = { "en", "fr", "ru" }; // Get all possible values var routeLanguage = (filt

是否可以以某种方式调用C#中的内联
try
语句

我正在为我的网站检测语言,有时,由于某种原因,客户端的语言类似于
en GR
。NET抛出异常。所以我需要使用
try
catch
,即使我没有真正捕捉到任何东西

在这种情况下,这似乎是一种完全的矫枉过正

// 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)
{
}
编辑
我无法修复异常,因为我无法控制用户在其区域性信息中的内容。NET只是将en FR视为无效语句。

您是否尝试过完全删除
try/catch
语句

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;
    }
}
仅在处理无法控制的异常时使用try/catch。顾名思义,异常应用于处理异常情况


在本例中,您正在执行标准解析,因此最好执行防御性编程,而不是尝试、抛出、捕获

你所做的是正确的方法。你说过,为什么你不能摆脱这个异常(我假设是这样)。所以你必须处理它。唉,C#没有一个try-catch作为表达式(不确定该如何工作——catch“子句”需要返回一个值)


或者,您可以构建一个小助手函数,该函数接受
Func
,调用它并将值传递给调用者。如果发生异常,它将返回(例如)
default(T)
。这样可以消除大量的混乱,并且可以重复使用。

首先,最好先弄清楚如何避免异常。首先集中精力。抛出该异常是有原因的,如果您可以确定它是什么,那么就不要这样做

要真正回答您的问题:没有现成的“吃掉此表达式中的所有异常”机制,但构建自己的机制很简单:

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; }
静态T异常(Func Func)
{
尝试{return func();}catch{}
返回默认值(T);
}
...
clientLanguage=(filterContext.HttpContext.Request.UserLanguages!=null)?
EatExceptions(()=>new CultureInfo(filterContext.HttpContext.Request.UserLanguages[0])。TwoLetterIsLanguageName):
空;}
如果有人试图在我正在审阅的代码中使用这样的诡计,那么我会。。。好吧,我们只能说,更改不会被签入。99%的时候,吃这样的食物是一个非常糟糕的主意。再一次:找出你做错了什么并停止做它。不要做错事,然后处理失败。

好吧,撇开关于预检查的(好)建议不谈,有几种相当普通/平淡无奇/显而易见的方法可以做到这一点:

首先,您可以将其包装在函数中。我想这对你来说还不够普遍

或者,您可以折叠
catch
分支:

try
{
    clientLanguage = (filterContext.HttpContext.Request.UserLanguages != null) ? new CultureInfo(filterContext.HttpContext.Request.UserLanguages[0]).TwoLetterISOLanguageName : null; // Exception sometimes without `try`
} catch (Exception) { }
或者,你可以把整个东西折叠成一行:

try { clientLanguage = (filterContext.HttpContext.Request.UserLanguages != null) ? new CultureInfo(filterContext.HttpContext.Request.UserLanguages[0]).TwoLetterISOLanguageName : null; } catch (Exception) { }

不优雅,但简单,而且有效。

首先尽量避免例外情况。仅仅因为字符串来自您无法控制的源,并不意味着您无法验证它

如果无法避免,则应捕获预期的特定异常,并将该逻辑封装到方法中。不要捕获所有异常

例如:

public static CultureInfo TryGetCultureByName(string name)
{
   try
   {
     return new CultureInfo(name);
   }
   catch(CultureNotFoundException)//Only catching CultureNotFoundException
   {
     return null;
   }
}
这样,如果您以后发现更好的方法来处理此特定错误,您可以轻松地替换它

例如,您可以创建一个
字典
,从
CultureInfo.GetCultures()
中填充它,并使用
TryGetValue
查找区域性,而不会引发异常

_.Try(() => __YourStatementHere__ );
使用一个像这样的小助手类:

/// <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 {
        }
    }

}
//
///其他实用功能。
/// 
公共静态类{
/// 
///尝试执行给定的操作。如果失败,则什么也不会发生。
/// 
公共静态无效尝试(操作){
试一试{
动作();
}
抓住{
}
}
}

我知道,这个解决方案也不是最优的,但到目前为止,它是我能找到的最简洁的解决方案。

我已经构建了一个在线的try-catch机制,可以满足这个目的。我想要一种类似LINQ或回调函数-y的语法。这是通过使用两个包装器、一个TryWrapper和一个CatchWrapper来完成的,这样点操作符就可以适当地提示下一步,隐式地转换为T类型

你也可以这样做

Try(() => UpdateSweetGreen("21", SweetGreen))
.Catch(LogToDb(e.Message))
.Catch(LogToFile(e.Message).Finally(ReportNewSweetGreen(SweetGreen);
基本上,CatchWrapper扩展了TryWrapper。因此,您可以从另一个catch块捕获异常。在本例中,将方法的故障记录到数据库中,然后如果该故障记录到文件中,则不管如何,都会将SweetGreen变量报告给其他组件

这一切都是从TryWrapper开始的
公共类TryWrapper
{
受保护的内部T结果{get;set;}=default(T);
受保护的内部异常异常{get;set;}=null;
公共静态隐式运算符T(TryWrapper包装器)
{
返回包装器.Result;
}
公共静态隐式运算符异常(TryWrapper包装器)
{
返回包装器.Exception;
}
}
和CatchWrapper,它只是扩展了TryWrapper,不能直接调用,只能在尝试后出现,正如您在标准实现中所期望的那样
公共类CatchWrapper:TryWrapper
{
}
然后提出了一系列的静态扩展方法
public static TryWrapper Try(Func-Func)
{
var product=新TryWrapper();
尝试
{
product.Result=func.Invoke();
}
捕获(例外e)
{
product.Exception=e;
}
退货产品;
}
公共静态TryWrapper Try(操作操作)
{
var product=新TryWrapper();
尝试
    public class TryWrapper<T>
    {
        protected internal T Result { get; set; } = default(T);

        protected internal Exception Exception { get; set; } = null;

        public static implicit operator T(TryWrapper<T> wrapper)
        {
            return wrapper.Result;
        }

        public static implicit operator Exception(TryWrapper<T> wrapper)
        {
            return wrapper.Exception;
        }
    }
    public class CatchWrapper<T> : TryWrapper<T>
    {
    }
        public static TryWrapper<T> Try<T>(Func<T> func)
        {
            var product = new TryWrapper<T>();

            try
            {
                product.Result = func.Invoke();
            }
            catch (Exception e)
            {
                product.Exception = e;
            }

            return product;
        }

        public static TryWrapper<T> Try<T>(Action action)
        {
            var product = new TryWrapper<T>();

            try
            {
                action.Invoke();
            }
            catch (Exception e)
            {
                product.Exception = e;
            }

            return product;
        }

        public static CatchWrapper<T> Catch<T>(this TryWrapper<T> wrapper, Action<Exception> response)
        {
            if (wrapper.Exception is null) return wrapper as CatchWrapper<T>;

            response.Invoke(wrapper);
            wrapper.Exception = null;

            return wrapper as CatchWrapper<T>;
        }


        public static TryWrapper<T> Finally<T>(this TryWrapper<T> wrapper, Action<T> response)
        {
            response.Invoke(wrapper);

            return wrapper;
        }

        public static TryWrapper<T> Finally<T>(this TryWrapper<T> wrapper, Func<T> response)
        {
            wrapper.Result = response.Invoke();

            return wrapper;
        }

        public static TryWrapper<T> Finally<T>(this TryWrapper<T> wrapper, Action response)
        {
            response.Invoke();

            return wrapper;
        }