Thursday, March 14, 2013

Dynamic C#

using System.Dynamic;

public class Employee
{
 public string FirstName {get; set;}

 public void Speak()
 {
  Console.WriteLine("Hi, my name is {0}", FirstName);
 }
}
class Program
{
 static void Main(string[] args)
 {
  //old method
  object o = GetASpeaker();
  o.GetType().GetMethod("Speak").Invoke(0, null);
 
  //dynamic object
  dynamic o = GetASpeaker();
  o.Speak();
 
  //loading 3rd-party assembly and dynamic object
  Type dogType = Assembly.Load("Dogs").GetType("Dog");
  dynamic dog = Activator.CreateInstance(dogType);
  dog.Speak();
 
  //excel automation and dynamic object
  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;
  }
 
  //expandoobject
  dynamic expando = new ExpandoObject();
  //or, dynamic expando = new ExpandoObject() as IDictionary<string, object>;
  expando.Name = "The";
  //or, expando["Name"] = "The"
  expando.Speak = new Action(() => Console.WriteLine(expando.Name));
 
  foreach(var member in expando)
  {
   Console.WriteLine(member.Key);
  }
 
  expando.Speak();
 
  //implements dynamicobject interface
  dynamic doc = new DynamicXml("Employees.xml");
  foreach(var employee in doc.Employees)
  {
   Console.WriteLine(employee.FirstName);
  }
 
  //C# and IronRuby interaction
 
  // running .rb file with passed c# object
  var engine = IronRuby.Ruby.CreateEngine();
  var scope = engine.CreateScope();
  scope.SetVariable("employee", new Employee { FirstName = "The C#"});
  engine.ExecuteFile("Program.rb", scope);
 
  // instantiates classes from .rb file in c# code
  dynamic ruby = engine.Runtime.Globals;
  dynamic person = ruby.Person.@new();
  person.firstName = "The Ruby";
  person.speak();
 }

 private static object GetASpeaker()
 {
  return new Employee { FirstName = "Scott" };
 }
}
internal class DynamicXml : System.Dynamic.DynamicObject, System.Collections.IEnumerable
{
 private dynamic _xml;

 public DynamicXml(string fileName)
 {
  _xml = XDocument.Load(fileName);
 }

 public DynamicXml(dynamic xml)
 {
  _xml = xml;
 }

 public override bool TryGetMember(GetMemberBinder binder, out object results)
 {
  var xml = _xml.Element(binder.Name);
  if(xml != null)
  {
   result = new DynamicXml(xml);
   return true;
  }
 
  result = null;
  return false;
 }

 public IEnumerator GetEnumerator()
 {
  foreach(var child in _xml.Elements())
  {
   yield return new DynamicXml(child);
  }
 }
}

Program.rb
class Person
 attr_accessor :firstName

 def speak
  puts @firstName
 end
end
employee.Speak

Reference: Scott Allen's C# Fundamentals Part 2

No comments: