Building on some of the other answers here, the dynamic objects are really JSON objects that are returned from the facebook api. The SDK uses dynamic type to create a nicer interface to the underlying data.
I didn't like the idea of casting the objects to IDictionary each time so I took it a step further and created a facade object that provides a strongly-typed access method to the data.
public class FBPerson : FBBase
{
#region constructor
public FBPerson(object personObject)
: base(personObject)
{
}
#endregion
#region Properties
public string first_name
{
get { return ExtractValueAsString("first_name"); }
}
public string last_name
{
get { return ExtractValueAsString("last_name"); }
}
public string name
{
get { return ExtractValueAsString("name"); }
}
public string email
{
get { return ExtractValueAsString("email"); }
}
public string id
{
get { return ExtractValueAsString("id"); }
}
public string link
{
get { return ExtractValueAsString("link"); }
}
public string username
{
get { return ExtractValueAsString("username"); }
}
public string location
{
get { return ExtractValueAsString("location"); }
}
public string gender
{
get { return ExtractValueAsString("gender"); }
}
public string timezone
{
get { return ExtractValueAsString("timezone"); }
}
public string locale
{
get { return ExtractValueAsString("locale"); }
}
public string verified
{
get { return ExtractValueAsString("verified"); }
}
public string updated_time
{
get { return ExtractValueAsString("updated_time"); }
}
#endregion
}
And the base class (so you can create facades for other SDK objects)...
public class FBBase
{
private IDictionary<string, object> fbCollection = null;
public FBBase(object collection)
{
fbCollection = (IDictionary<string, object>)collection;
}
protected string ExtractValueAsString(string value)
{
Validate();
return fbCollection[value].ToString();
}
protected void Validate()
{
if (fbCollection == null)
{
throw new InvalidOperationException("null collection object");
}
}
}