views:

60

answers:

5

What would be the best way to deserialize this

Dictionary<string, object>{
   {"fName", "John"},
   {"lName", "Doe"},
   {"email", "[email protected]"}
}

to this

class Member{
   string fName;
   string lName;
   string email;
}
+2  A: 

This isn't really serialization in the normal sense, that usually refers to taking some disk or network formatted data (binary, ASCII, JSON etc) and loading it into a runtime object.

However, if I understand you correctly, I think what you are trying to do is...

public Member( Dictionary<string,object> dictionary )
{ 
    fName = dictionary["fName"];
    lName = dictionary["lName"];
    email = dictionary["email"];
}

// usage Member m = new Member( inputDictionary );
BioBuckyBall
I was thinking about that, but I don't like the idea of hard-coding any values. That's why I am asking about the best way, if there is any avoiding this approach. Simply I was looking for something like this `Member member = (Member)myDictionary;`
negative
I would put it in a constructor for `Member` that takes a dictionary as a parameter. Adding to answer...
BioBuckyBall
If you want to avoid the hard coded key values, then I would use a reflection based technique like @KiethS offered
BioBuckyBall
@negative: so the items are always going to be 3? or could be more? like fName, lName, email, and Address, for instance.
KMan
@KMan, yes, it will be more, `Member` class is given as an example.
negative
+1  A: 

If the structure is static:

return new Member 
{
   fName = myDictionary["fName"], 
   lName = myDictionary["lName"], 
   email = myDictionary["email"]
};

If the structure is not known at design time:

public static T Hydrate<T>(this Dictionary<string, string> theDictionary, 
   T myObject = new T()) where T:new() //default/optional parameter is valid in 4.0 only
{

   //var myObject = myObject ?? new T(); //alternative in 3.5 and previous

   foreach(string key in myDictionary.Keys)
   {
      var propInfo = typeof(T).GetProperty(key);

      if(propInfo == null) throw new ArgumentException("key does not exist");
      propInfo.SetValue(myObject, theDictionary[key], null);
   }
   return myObject;
}
KeithS
I think there must something wrong with my class, because `typeof(T).GetProperty(key)` is always null and `typeof(T).GetProperties()` is empty. Same as `typeof(Member).GetProperties()`
negative
A: 

One approach that seems to make sense would be to have a static helper function for this.

public static Member Create(Dictionary<string, object inputs)
{
    Member oNew = new Member();
    oNew.fName = inputs["fName"].ToString();
    // etc
    return oNew;
}
Mitchel Sellers
A: 

You could also use reflection to this, it could be a lot of code depending on the objects you're actually using, but it would be a lot more flexible. This probably isn't a complete sample, but it gets you the general idea.

public T InstantiateFromDictionary<T>(Dictionary<string, object> values) where T : new()
{
   Type t = typeof(T);
   T instance = new T();
   foreach(KeyValuePair<string, object> kvp in values)
   {
        PropertyInfo prop = t.GetProperty(kvp.Key);
        prop.SetValue(instance, kvp.Value, null);
   }

   return instance;
}
Coding Gorilla
A: 

This isn't serialization, it's conversion. If you really want it convertible, then make it convertible. Implement TypeConverter.

Example code

using System;

using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Xml.Linq; using System.Diagnostics; using System.Xml.Serialization; using System.ComponentModel; using System.Globalization;

namespace ConsoleApplication1 {

internal class MemberConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context,
  Type sourceType)
    {
        if (sourceType == typeof(Dictionary<string, object>))
        {
            return true;
        }
        return base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context,
  CultureInfo culture, object value)
    {
        if (value is Dictionary<string, object>)
        {
            Member member = new Member();
            Dictionary<string, object> d = (Dictionary<string, object>)value;
            if (d.ContainsKey("fName")) { member.fName = Convert.ToString(d["fName"]); };
            if (d.ContainsKey("lName")) { member.lName = Convert.ToString(d["lName"]); };
            if (d.ContainsKey("email")) { member.email = Convert.ToString(d["email"]); };
            return member;
        }
        return base.ConvertFrom(context, culture, value);
    }

    public override object ConvertTo(ITypeDescriptorContext context,
  CultureInfo culture, object value, Type destinationType)
    {
        if (destinationType == typeof(Dictionary<string, object>))
        {
            Member member = (Member)value;
            Dictionary<string, object> d = new Dictionary<string, object>();
            d.Add("fName", member.fName);
            d.Add("lName", member.lName);
            d.Add("email", member.email);
            return d;
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }

}

[TypeConverter(typeof(MemberConverter))]
internal class Member
{
    public string fName;
    public string lName;
    public string email;
}

class Program
{
    static void Main(string[] args)
    {
        var d = new Dictionary<string, object> {
           {"fName", "John"},
           {"lName", "Doe"},
           {"email", "[email protected]"}
        };

        Member m = (Member)TypeDescriptor.GetConverter(typeof(Member)).ConvertFrom(d);

        Debugger.Break();
    }
}

}

Nikki9696