.NET4.0 new runtime on top of the CLR to support dynamic languages – DLR.. Ruby and Python.
Why Dynamic?
Static: C#, F#, C
Dynamic: JavaScript, Python,Ruby, PHP .. generally.. allow to modify code and types at runtime. No compiler. So only perform type checking at runtime (if at all)
When the compiler sees the dynamic keyword, it turns off compile time checks.
class Program {
static void Main() {
//Object o = GetASpeaker();
// Cooerce GetASpeaker as an Employee
//Employee o = GetASpeaker() as Employee;
//Use reflection.. if we know there is a Speak method
//o.GetType().GetMethod("Speak").Invoke(o,null);
//o.Speak();
dynamic o = GetASpeaker();
o.Speak();
}
private static object GetASpeaker() {
return new Employee { FirstName = "Scott" };
}
}
public class Employee {
public string FirstName { get; set; }
public void Speak() {
Console.WriteLine("Hi, my name is {0}", FirstName);
}
}
It works.
Com Interop – Excel
Type excelType = Type.GetTypeFromProgID("Excel.Application");
dynamic excel = Activator.CreateInstance(excelType);
excel.Visible = true;
excel.Workbooks.Add();
dynamic sheet = excel.ActiveSheet;
Process[] processes = Process.GetProcesses();
for (int i = 0; i < processes.Length; i++)
{
sheet.Cells[i + 1, "A"] = processes[i].ProcessName;
sheet.Cells[i + 1, "B"] = processes[i].Threads.Count;
}
Expando
dynamic expando = new ExpandoObject();
expando.Name = "Scott";
expando.Speak = new Action(() => Console.WriteLine(expando.Name));
//expando.Speak();
foreach (var member in expando)
{
Console.WriteLine(member.Key);
}
prints Name, Speak
Parse an XML file:
// XDocument is in System.Xml.Linc
var doc = XDocument.Load("Employees.xml");
foreach (var element in doc.Element("Employees")
.Elements("Employee")) {
Console.WriteLine(element.Element("FirstName").Value);
}
// Expando objects in expando
var doc2 = XDocument.Load("Employees.xml").AsExpando();
foreach (var employee in doc2.Employees)
{
Console.WriteLine(employee.FirstName);
}
then a simple extension method:
public static class ExpandoXml
{
public static dynamic AsExpando(this XDocument document)
{
return CreateExpando(document.Root);
}
private static dynamic CreateExpando(XElement element)
{
var result = new ExpandoObject() as IDictionary<string, object>;
if (element.Elements().Any(e => e.HasElements))
{
var list = new List<ExpandoObject>();
result.Add(element.Name.ToString(), list);
foreach (var childElement in element.Elements())
{
list.Add(CreateExpando(childElement));
}
}
else
{
foreach (var leafElement in element.Elements())
{
result.Add(leafElement.Name.ToString(), leafElement.Value);
}
}
return result;
}
}
CreateExpando is a recursive function that calls itself.
DynamicObject
A bit of work – but lots of power here.