Dorian
Dorian

Reputation: 983

how to convert list<keyvalue<string,string>> to some type

im working on some refactoring of old code so there is a place where from api i have

 List<KeyValuePair<string, string>>

where key is propertyname and val is somevalue so example is

{ 
  key:"Login", val:"adam",
  key:"Name",val:"xxx",
  key:"Age", val:"12"
}

and now i have lets say

 public class UserModel
{
 public string? Login { get; set; }
 public string? Name{ get; set; }
 public int age{ get; set; }
}

and i need to convert this list to usermodel class how to do that ?

i have now

private  T GetItem<T>(List<KeyValuePair<string, string>> item)
{
    Type temp = typeof(T);
    T obj = Activator.CreateInstance<T>();

        foreach (PropertyInfo pro in temp.GetProperties())
        {
        string propName = pro.Name;

        string? val = item.Where(x => x.Key == propName).SingleOrDefault().Value;
        if (val == "NULL") val = null;

        Type t = pro.GetType();
        if (t == typeof(string)) pro.SetValue(obj, val, null);
        else 
        if (t == typeof(int?))
        {              
            int intVal = 0;
            if (!int.TryParse(val, out intVal)) pro.SetValue(obj, null, null);
            else
            pro.SetValue(obj, intVal, null);
        }  
        else
            pro.SetValue(obj, null, null);

    }

    return obj;
}

but this do not work because usermodel types are nullable string not string and i canot do

  if (t == typeof(string?))

because typeof canot be on nullable types (why on int? i can!?)

please advice best regards

Upvotes: -1

Views: 37

Answers (1)

R4ffi
R4ffi

Reputation: 31

Instead of handling each type individually, I would recommend using Convert.ChangeType. This works as long as the IConversible interface is implemented.

In your example, the method would then look like this:

private T GetItem<T>(List<KeyValuePair<string, string>> item)
{
    var typeOfT = typeof(T);
    var newObject = Activator.CreateInstance<T>();

    foreach (var propertyInfo in typeOfT.GetProperties())
    {
        var textValue = item.Where(x => x.Key == propertyInfo.Name).SingleOrDefault().Value;
        var value = Convert.ChangeType(textValue, propertyInfo.PropertyType);
        propertyInfo.SetValue(newObject, value);
    }

    return newObject;
}

Upvotes: 1

Related Questions