Доступ к элементам словаря в свойстве Data класса исключения - PullRequest
0 голосов
/ 04 мая 2018

У меня проблемы с доступом к значениям свойства data класса Exception.

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 Не удалось неявно преобразовать тип «объект» в «строку». существует явное преобразование (вам не хватает приведения?)

Все ссылки, которые я могу найти, получают доступ к этой информации с помощью циклов foreach, определяющих тип как DictionaryEntry, но это не является необходимым / нежелательным для этого экземпляра:

Как мне извлечь один элемент из этого словаря?

UPDATE

Что касается предложения @ dbc о создании пользовательского класса исключений, то здесь есть ссылка, в которой более подробно рассказывается, почему я этого не сделал.

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

Не стесняйтесь комментировать, почему класс исключений будет лучше, чем использование свойства data базового класса исключений.

1 Ответ

0 голосов
/ 04 мая 2018

Exception.Data является нетипизированным IDictionary:

public virtual IDictionary Data { get; }

Поэтому методы доступа get и set возвращают и принимают значение типа object, которое необходимо преобразовать или преобразовать в нужный тип, например ::

public const string ExceptionMessageKey = "UI Error Message";

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

(где ?. - условный оператор c # 6.0 null ). Или альтернативно:

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

Кроме того, если вы более знакомы с универсальным интерфейсом IDictionary<TKey, TValue>, обратите внимание на следующее отличие. При использовании нетипизированного IDictionary и доступе к ключу, который не существует, документация получателя заявляет :

Стоимость объекта

Элемент с указанным ключом или null , если ключ не существует.

Напротив, в документации IDictionary<TKey, TValue> указано, что KeyNotFoundException будет выброшено, когда ключ не найден. Нет TryGetGetValue() для IDictionary.

Пример скрипта .Net здесь .

Update

Кроме того, является ли ключевое слово const обязательным или просто наилучшей практикой в ​​этом случае? Использование const здесь является исключительно хорошей практикой. Поскольку вы собираетесь получать и устанавливать подробности исключений в своем словаре Data со стандартизованными ключами, хорошей идеей будет централизовать фактические значения этих ключей в одном месте вашего кода, который может использоваться как производителями, так и потребителями вашего Exception, например класс статических констант :

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

Кроме того, почему нужно объявить строковую константу перед использованием свойства data класса исключений? - в этом нет необходимости. Я сделал это только для того, чтобы сделать значение ExceptionMessageKey публичной константой.

Когда я использую условный оператор null с обрисованным вами синтаксисом, я получаю ошибку времени компиляции, говорящую «Синтаксическая ошибка»: «ожидается». - тогда вы, вероятно, используете версию c # ранее чем 6.0. Если это так, вы можете использовать следующий более старый синтаксис:

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

Наконец, как уже упоминалось в Обработка и создание исключений в .NET Хорошей практикой является использование более подходящего производного типа Exception. Вы можете выбрать общий, ранее существовавший тип, такой как ApplicationException или , определить свой собственный , и в этом случае «Сообщение об ошибке пользовательского интерфейса» может быть сделано скорее как свойство исключения чем запись в словаре Data.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...