我无法访问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属性更好。
答案 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表示在找不到密钥时会抛出KeyNotFoundException
。 TryGetGetValue()
没有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
派生类型是一种好习惯。您可以选择常见的预先存在的类型,例如ApplicationException
或define your own,在这种情况下,&#34; UI错误消息&#34;可以成为异常的属性,而不是Data
字典中的条目。