Я хочу создать один метод, который будет отвечать за получение значения на основе входного ключа 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()
, но потом в реквизите вызывающего абонента public string? CorrelationId { get; set; } = GetValueForKeyFromHeader("CorrelationId");
у меня следующая ошибка:Learn.microsoft.com/en-us/dotnet/csharp/misc/…
@JohnWu в основном мне нужно извлечь все элементы значений из всех элементов объекта IDictionary..
@ Stefan0309 Stefan0309 Итак, вы пытались указать аргумент типа, который нельзя вывести? Например GetValueForKeyFromHeader<string>("CorrelationId")
?
да, вы правы, но все же у меня есть ошибка на моем пропе: public string HttpMethod { get { return GetValueForKeyFromHeader<string>("http_method"); } }
ошибка: HttpMethod = 'eventData.HttpMethod' threw an exception of type 'System.InvalidCastException'
Он никогда не входит в этот метод GetValueForKeyFromHeader<string>("http_method")
Вы передаете два типа в Convert.ChangeType
, первый аргумент должен быть объектом, который нужно преобразовать
По моему опыту, 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));
Видимо, вы имели в виду
value.GetType()
?