【问题标题】:How to get variable name in catch block?如何在 catch 块中获取变量名?
【发布时间】:2021-09-25 06:53:27
【问题描述】:

这里我分配了多个 string 变量,但我想捕捉变量及其名称的错误。

try
{
    sSrNo = Convert.ToString(valueArrayCustomerDetails[row, 1]);
    sNotice_No = (string)valueArrayCustomerDetails[row, 2];
    dt_notice_date = Convert.ToDateTime(valueArrayCustomerDetails[row, 3]);
    sAgreement_No = Convert.ToString(valueArrayCustomerDetails[row, 4]);
    sBorrower = (string)valueArrayCustomerDetails[row, 5];
}
catch (Exception ex)
{
    MessageBox.Show(ex.ToString() + "\n Error At :- Row-" + row + " Column-"); // here i want variable name at which error occurs
    throw;
}

【问题讨论】:

  • 如果您想处理每个变量的情况,可以查看TryParse 方法和/或将每个分配包装在try/catch 中。
  • 最明显的是对您要解析的每个变量使用多个try/catch
  • @Sinatr 是的,我不想为每个变量使用多个“try/catch”。请指教。
  • 要重构的是very easy
  • 我建议您查看异常并尝试首先防止它们发生,例如使用TryParse as string 和类似的

标签: c# .net variables try-catch


【解决方案1】:

好吧,如果你想要这些信息,你必须使用多个 try-catch:

try
{
    sSrNo = Convert.ToString(valueArrayCustomerDetails[row, 1]);
}
catch (Exception ex)
{
    MessageBox.Show(ex.ToString() + "\n Error At :- Row-" + row + " 1"); 
    throw;
} 

try
{
    sNotice_No = (string)valueArrayCustomerDetails[row, 2];
}
catch (Exception ex)
{
    MessageBox.Show(ex.ToString() + "\n Error At :- Row-" + row + " 2"); 
    throw;
}

// ...

另一种选择是创建一个这样的辅助方法:

public static class Utils
{
    public static T TryDo<T>(Func<T> returnMethod, Action<Exception> exceptionAction = null, bool throwOnException = true, T fallbackValue = default(T))
    {
        try
        {
            return returnMethod();
        }catch(Exception ex)
        {
            exceptionAction(ex);
            if(throwOnException)
            {
                throw;
            }
        }
        
        return fallbackValue;
    }
}

现在你可以使用这个简洁易读的代码了:

sSrNo = Utils.TryDo(() => Convert.ToString(valueArrayCustomerDetails[row, 1]), ex => MessageBox.Show(GetMessage(ex, row, 1)));
sNotice_No = Utils.TryDo(() => Convert.ToString(valueArrayCustomerDetails[row, 2]), ex => MessageBox.Show(GetMessage(ex, row, 2)));
dt_notice_date = Utils.TryDo(() => Convert.ToDateTime(valueArrayCustomerDetails[row, 3]), ex => MessageBox.Show(GetMessage(ex, row, 3)));
sAgreement_No = Utils.TryDo(() => Convert.ToString(valueArrayCustomerDetails[row, 4]), ex => MessageBox.Show(GetMessage(ex, row, 4)));
sBorrower = Utils.TryDo(() => Convert.ToString(valueArrayCustomerDetails[row, 5]), ex => MessageBox.Show(GetMessage(ex, row, 5)));

// local method
string GetMessage(Exception ex, int row, int col) 
    => $"{ex.ToString()} Error At :- Row-{row} Column-{col}";

【讨论】:

  • 完全避免代价高昂的例外情况不是要走的路吗?
  • @UweKeim 如果它们经常发生,它们只是代价高昂。我对 OP 的用例一无所知,也不知道是否有例外。所以我专注于问题本身
【解决方案2】:
string index="1";
try
{
    sSrNo = Convert.ToString(valueArrayCustomerDetails[row, 1]);
index="2";
sNotice_No = (string)valueArrayCustomerDetails[row, 2];
index="3";
dt_notice_date = 
Convert.ToDateTime(valueArrayCustomerDetails[row, 3]);
index="4";
sAgreement_No = 
Convert.ToString(valueArrayCustomerDetails[row, 4]);
index="5";
sBorrower = (string)valueArrayCustomerDetails[row, 5];
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString() + "\n Error At :- Row-" + row + " 
Column-"+index); // here i want variable name at which error occurs
throw;
}

【讨论】:

    【解决方案3】:

    试试这个:

    它将给出引发异常的行号,从而获取变量。

    catch(Exception ex)
    {
    var LineNumber = new StackTrace(ex, true).GetFrame(0).GetFileLineNumber();
    
    MessageBox.Show(ex.StackTrace + "\n Error at :- Row-" + LineNumber);
    }
    

    ex.StackTrace 给出详细的错误信息。

    【讨论】:

    • 一个可能的 improvement 显示 index 作为 OP 想要的。
    猜你喜欢
    • 1970-01-01
    • 2014-06-23
    • 2015-01-26
    • 2013-11-07
    • 2013-02-08
    • 1970-01-01
    • 2017-12-10
    • 2014-06-20
    • 1970-01-01
    相关资源
    最近更新 更多