Bruce Ge

  Home  |   Contact  |   Syndication    |   Login
  6 Posts | 0 Stories | 11 Comments | 0 Trackbacks

News

Archives

Post Categories

Tuesday, November 10, 2009 #

We all know the usage of the anonymous type:

var obj = new { Name = "John", Age = 24 };

What if we want to add a anonymous delegate or Lamba to it?

Like:

var obj = new { Name = "John", Age = 24, behaviour=delegate(string name, int age) { return "Customer Name: " + name + ", Age: " + age; } };

or

var obj = new { Name = "John", Age = 24, behaviour = (name, age) => string.Format( "Hello, {0}! You are {1} years old.", name, age ) };

The above two will cause compile time error, because anonymous type need anonymous type property, not the anonymous method or lambda expression.

There is some way to do it:

1. define a Func:

Func<string, int, string> behav =delegate(string name, int age)
            {
               return "Customer Name: " + name + ", Age: " + age;
            };

 

then we can do it:

var obj = new {Name = "John", Age = 24, behaviour = behav };

2. declare a delegate:

delegate string behav(string name, int age);

then we can do:

var obj = new { Name = "John", Age = 24, behaviour = (behav)delegate(string name, int age) { return "Customer Name: " + name + ", Age: " + age; } };

or

var obj = new { Name = "John", Age = 24, behaviour = (behav)((name, age) => string.Format("Hello, {0}! You are {1} years old.", name, age)) };

This is the demonstration only, if we want to use IEnumerable<AnonymousType>, as anonymous type can only be cast as object, there is article here to describe how to use it. Here is another solution:

class Foo<TName, TAge, TBehaviour>
{
    public List<object> Collection { get; set; }
 
    public Foo()
    {
        Collection = new List<object>();
    }
 
    public void AddValue(TName name, TAge age, TBehaviour func)
    {
        var cust = new { CustomerName = name, Customerage = age, Behaviour = func };
        Collection.Add(cust);
    }
}
 
static T Cast<T>(object obj, T type)
{
    return (T)obj;
}
 
static void Main(string[] args)
{
    Func<string, int, string> behav =
    delegate(string name, int age)
    {
        return "Customer Name: " + name + ", Age: " + age;
    };
    var _foo = new Foo<string, int, Func<string, int, string>>();
 
    _foo.AddValue("John", 24, behav);
    _foo.AddValue("Tom", 26, delegate(string name, int age) { return "Customer Name: " + name + ", Age: " + age; });
    _foo.AddValue("Tim", 30, (name, age) => string.Format("Hello, {0}! You are {1} years old.", name, age));
    var typeinfo = new { CustomerName = "", Customerage = 0, Behaviour = behav };
    foreach (var customer in _foo.Collection)
    {
        var typed = Cast(customer, typeinfo);
        Console.WriteLine(typed.Behaviour(typed.CustomerName, typed.Customerage));
    }
}

 

Otherwise we can do it without anonymous type as below:

 

        public class Customer<TCustomerName, TCustomerAge, TFunction>
        {
            public TCustomerName CustomerName { get; set; }
            public TCustomerAge Customerage { get; set; }
            public TFunction Behaviour { get; set; }
        }
        public class Foo<TName, TAge, TBehaviour>
        {
            public List<Customer<TName, TAge, TBehaviour>> Collection { get; set; }
 
            public Foo()
            {
                Collection = new List<Customer<TName, TAge, TBehaviour>>();
            }
 
            public void AddValue(TName name, TAge age, TBehaviour func)
            {
                var cust = new Customer<TName, TAge, TBehaviour>
                    {CustomerName = name, Customerage = age, Behaviour = func};
                Collection.Add(cust);
            }
        }
 
        static void Main(string[] args)
        {
 
            Func<string, int, string> behav =
            delegate(string name, int age)
            {
                return "Customer Name: " + name + ", Age: " + age;
            };
            var _foo = new Foo<string, int, Func<string, int, string>>();
 
            _foo.AddValue("John", 24, behav);
            _foo.AddValue("Tom", 26, delegate(string name, int age) { return "Customer Name: " + name + ", Age: " + age; });
            _foo.AddValue("Tim", 30, (name, age) => string.Format("Hello, {0}! You are {1} years old.", name, age));
            foreach (var customer in _foo.Collection)
                Console.WriteLine(customer.Behaviour(customer.CustomerName, customer.Customerage));
        } 

 

In .Net 4.0, you even can do it more flexible by using dynamic type:

class Foo
{
    public List<object> Collection { get; set; }
 
    public Foo()
    {
        Collection = new List<object>();
    }
 
    public void AddValue(dynamic name, dynamic age, Func<dynamic, dynamic, dynamic> func)
    {
        var cust = new { CustomerName = name, Customerage = age, Behaviour = func };
        Collection.Add(cust);
    }
}
 
static T Cast<T>(object obj, T type)
{
    return (T)obj;
}
 
static void Main(string[] args)
{
    Func<dynamic, dynamic, dynamic> behav =
    delegate(dynamic name, dynamic age)
    {
        return "Customer Name: " + name + ", Age: " + age;
    };
    var _foo = new Foo();
 
    _foo.AddValue("John", 24, behav);
    _foo.AddValue(DateTime.Now, 26, delegate(dynamic name, dynamic age) { return "Customer Name: " + name + ", Age: " + age; });
    _foo.AddValue(Int32.MaxValue, 30, (name, age) => string.Format("Hello, {0}! You are {1} years old.", name, age));
    var typeinfo = new { CustomerName = (dynamic)"", Customerage = (dynamic)0, Behaviour = behav };
    foreach (var customer in _foo.Collection)
    {
        var typed = Cast(customer, typeinfo);
        Console.WriteLine(typed.Behaviour(typed.CustomerName, typed.Customerage));
    }
    Console.Read();
}

 

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati