访问异常类数据属性中的字典项

时间:2018-05-03 21:31:45

标签: c# .net exception

我无法访问Exception类的data属性值。

try
{
    string strReasonCode = String.Empty;
    string strReasonDescription = String.Empty;
    string strDuration = String.Empty;
    string strActive = String.Empty;

    if (ReasonCodeDT.Rows.Count != 1)
    {
        string strPracticeID = PracticeID.ToString();
        string PracticeName = getSingleStringResultFromSQL("SELECT @result = PracticeName FROM Practice WHERE PracticeID = /'" + strPracticeID + "/'"); 
        string RecordCount = ReasonCodeDT.Rows.Count.ToString();
        int UserID;
        Int32.TryParse(au.UserID, out UserID);
        Exception ex = new Exception("Database Returned " + RecordCount + " Records for ReasonCodeID " + ReasonCodeID + " for Practice " + PracticeName + " (" + strPracticeID + ")");
        ex.Data.Add("UI Error Message", "Whoops! Something went wrong there. Please call (555)555-5555" +
            "and notify them something is wrong with the Encounter Reason: " + ReasonCodeID);
        throw ex;
    }
    else
    {
    }
}
catch
{
    pnlError.Visible = true;
    lblErrorMessage.Text = ex.Data["UI Error Message"];
}

这给了我一个编译器错误消息:

  

错误117无法将类型'object'隐式转换为'string'。一个   存在显式转换(您是否错过了演员?)

我可以找到的所有引用通过使用foreach循环来指定类型为DictionaryEntry来访问该信息,但这对于此实例不是必需/可取的:

如何从该字典中检索单个项目?

更新

在参考@dbc关于创建自定义异常类的建议时,这里提供了一个链接,提供了有关我没有这样做的原因的详细信息。

https://blogs.msdn.microsoft.com/jaredpar/2008/10/20/custom-exceptions-when-should-you-create-them/

随意评论为什么异常类比使用基本异常类的data属性更好。

1 个答案:

答案 0 :(得分:3)

Exception.Data无类型IDictionary

public virtual IDictionary Data { get; }

因此,get and set accessors返回并获取object类型的值,您必须将其转换或转换为所需类型,例如:

public const string ExceptionMessageKey = "UI Error Message";

lblErrorMessage.Text = ex.Data[ExceptionMessageKey]?.ToString();

(其中?.是c#6.0 null conditional operator)。或者:

lblErrorMessage.Text = ex.Data[ExceptionMessageKey] as string;

顺便说一句,如果您更熟悉通用IDictionary<TKey, TValue>接口,请注意以下区别。使用无类型IDictionary并访问不存在的密钥时,getter文档states

  

物业价值

     

具有指定键的元素,如果该键不存在,则为 null

相反,IDictionary<TKey, TValue> documentation表示在找不到密钥时会抛出KeyNotFoundExceptionTryGetGetValue()没有IDictionary

示例.Net小提琴here

<强>更新

此外,在这种情况下const关键字是强制性的还是最佳做法?在这里使用const纯粹是一种很好的做法。由于您将使用标准化密钥在Data字典中获取和设置异常详细信息,因此最好将这些密钥的实际值集中在代码中的一个位置,以供两个生产者使用和Exception的消费者,例如一个static constants class

public static class Constants
{
    public const string ExceptionMessageKey = "UI Error Message";
}

另外,为什么必须在使用异常类的data属性之前声明字符串常量? - 这是不必要的。我这样做只是为了使ExceptionMessageKey的值成为公共常量。

当我使用带有你概述的语法的空条件运算符时,我得到一个编译时错误,说&#34;语法错误&#39;:&#39;预期&#34;。 - 那么你可能正在使用早于6.0的c#版本。如果是这样,您可以使用以下旧语法:

var value = ex.Data[Constants.ExceptionMessageKey];
string text = value == null ? null : value.ToString();

最后,正如Handling and throwing exceptions in .NET中提到的那样,抛出一些更合适的Exception派生类型是一种好习惯。您可以选择常见的预先存在的类型,例如ApplicationExceptiondefine your own,在这种情况下,&#34; UI错误消息&#34;可以成为异常的属性,而不是Data字典中的条目。