Как сделать общий метод для извлечения разных типов из Dictionary<string, object>

Я хочу создать один метод, который будет отвечать за получение значения на основе входного ключа arg и за поиск типа этого значения, потому что это объект (может быть int, string, datetime...)

Я создал что-то вроде этого:

public T GetValueForKeyFromHeader<T> (string key)
{
 object value = null;
 var hasValue = Headers?.TryGetValue(key, out value!); //IDcitionary<string, object>
 return (T)Convert.ChangeType(typeof(value), typeof(T)); 
//here on this line I have an error: 'value' is a variable but its used like a type
}

некоторые примеры этой коллекции IDictionary: //"apiKeyId", "руководство" //"CorrelationId", 333 // "тест": "привет мир"

Я хочу извлечь эти значения и поместить их в мою неанемичную модель для каждого свойства:

public string Test{get;set;} = GetValueForKeyFromHeader("test");
public int CorrelationId{get;set;} = GetValueForKeyFromHeader("CorrelationId");
public string ApiKeyId {get;set;} = GetValueForKeyFromHeader("api_key_id");

Видимо, вы имели в виду value.GetType()?

GSerg 21.11.2022 00:09

Проблема здесь в том, что заголовки могут иметь более одного значения, а вы искали одно значение.

John Wu 21.11.2022 00:09

Да, я уже пробовал с value.GetType(), но потом в реквизите вызывающего абонента public string? CorrelationId { get; set; } = GetValueForKeyFromHeader("CorrelationId"); у меня следующая ошибка:Learn.microsoft.com/en-us/dotnet/csharp/misc/…

Stefan0309 21.11.2022 00:12

@JohnWu в основном мне нужно извлечь все элементы значений из всех элементов объекта IDictionary..

Stefan0309 21.11.2022 00:13

@ Stefan0309 Stefan0309 Итак, вы пытались указать аргумент типа, который нельзя вывести? Например GetValueForKeyFromHeader<string>("CorrelationId")?

GSerg 21.11.2022 00:21

да, вы правы, но все же у меня есть ошибка на моем пропе: public string HttpMethod { get { return GetValueForKeyFromHeader<string>("http_method"); } } ошибка: HttpMethod = 'eventData.HttpMethod' threw an exception of type 'System.InvalidCastException' Он никогда не входит в этот метод GetValueForKeyFromHeader<string>("http_method")

Stefan0309 21.11.2022 00:48

Вы передаете два типа в Convert.ChangeType, первый аргумент должен быть объектом, который нужно преобразовать

BurnsBA 21.11.2022 16:20
Шаблоны Angular PrimeNg
Шаблоны Angular PrimeNg
Как привнести проверку типов в наши шаблоны Angular, использующие компоненты библиотеки PrimeNg, и настроить их отображение с помощью встроенной...
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Если вы веб-разработчик (или хотите им стать), то вы наверняка гик и вам нравятся "Звездные войны". А как бы вы хотели, чтобы фоном для вашего...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Начала с розового дизайна
Начала с розового дизайна
Pink Design - это система дизайна Appwrite с открытым исходным кодом для создания последовательных и многократно используемых пользовательских...
Шлюз в PHP
Шлюз в PHP
API-шлюз (AG) - это сервер, который действует как единая точка входа для набора микросервисов.
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
0
7
65
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

По моему опыту, TypeDescriptor — это путь:

public static bool TryGetValue<TValue>(this IDictionary<string, object> self, string key, out TValue value)
{
    if (!self.TryGetValue(key, out var _value))
    {
        value = default;
        return false;
    }
    if (_value is TValue casted)
    {
        value = casted;
        return true;
    }
    if (_value is string str)
    {
        var converter = TypeDescriptor.GetConverter(typeof(TValue));
        if (converter.CanConvertFrom(typeof(string)))
        {
            value = (TValue)converter.ConvertFromInvariantString(str);
            return true;
        }
    }
    value = default;
    return false;
}

Затем вы можете переписать свой метод:

public T GetValueForKeyFromHeader<T> (string key)
{
    return Headers?.TryGetValue(key, out var value) == true ? value : default;
}
Ответ принят как подходящий

Вы неправильно используете Convert.ChangeType, вам нужно передать объект, который вы хотите преобразовать.

return (T)Convert.ChangeType(value, typeof(T));

Поскольку вы на самом деле не используете результат TryGetValue, может быть проще просто получить доступ к объекту по его ключу. Если его не существует, вы получите KeyNotFoundException, на мой взгляд, это будет более понятно, чем InvalidCastException, который вы сейчас получаете за прохождение null.

var value = Headers[key];
return (T)Convert.ChangeType(value, typeof(T));

Другие вопросы по теме