In this article we will see how Expando Object class will help us to return an anonymous collection from a method.
Introduction
At our regular work, we do return known datatypes from our methods and it is preety common.But how about returning a something whose data type is not known to us!.
For example, we are familiar with
private List GetStringCollection()
{
// some meaningful code that will return a string collection
}
But how about
private List GetAnonymousCollection()
{
var result = (from item in items
select new
{
Property1= item.value1,
Property2= item.value2
}).ToList();
return result; // what is the data type of result? It is purely anonymous.
}
From the above code, the question that crops up is "what is the data type of result?" It is purely anonymous.People may argue that so what is the big deal.Here are the possible solutions
Solution1:Create a CONCRETE CLASS and type cast to it
Create a Class with those properties ,make a proper strongly type cast and return it. e.g.
class SomeConcreteClass
{
public int Property1 { set; get; }
public int Property2 { set; get; }
}
private List GetAnonymousCollection()
{
var result = (from item in items
select new SomeConcreteClass
{
Property1= item.value1,
Property2= item.value2
}).ToList();
return result;
}
Consider the case that we have been asked not to create a concreate class (say it's a business constraint).In that case this solution cannot be accepted. Also say many of such anonymous types are there and it is not feasible to create a concrete class for everything.Right!.So, this solution is not acceptable.
Solution2:Use DYNAMIC keyword
I believe that by this time everyone has come across the word "dynamic" (specially who are programming in dotnet4.0). If not please read this.
Let us see the implementation using the same.
private dynamic GetAnonymousCollection()
{
var result = (from item in items
select new SomeConcreteClass
{
Property1= item.value1,
Property2= item.value2
}).ToList();
return result;
}
Perfect!But suppose we want to further do some kind of LINQ operation (that involves JOIN/WHERE clause) using the result set.It is quite difficult to go ahead and we may encounter with
Query expressions over source type 'dynamic' or with a join sequence of type 'dynamic' are not allowed
Please read this article for more information.
Solution3:Use LIST
Let's see the implementation
private List<object> GetAnonymousCollection()
{
var result = (from item in items
select new
{
Property1= item.value1,
Property2= item.value2
}).ToList();
return result;
}
Alright.But we cannot get the properties directly and will get 
We can however do a nasty hack by using some loops but that is work around and not a feasible one.
The proposed solution:Use LIST<ExpandoObject>
We can however, achieve both the goals by using Expando Objects.For example
private LIST<ExpandoObject> GetAnonymousCollection()
{
var result = items
.Select(item =>
{
dynamic expandoObj = new ExpandoObject();
expandoObj.Property1 = item.value1;
expandoObj.Property2 = item.value2;
return (ExpandoObject)expandoObj;
}).ToList<ExpandoObject>();
return result;
}
So what is an Expando Object?
It represents an object whose members can be dynamically added and removed at runtime.It is defined in the System.Core assembly and belongs to System.Dynamic namespace.
A detailed look inside the Expando Object reveals the following

The Expando Class cannot be inherited as it is Sealed. It implements six different interfaces. Out of which the below two needs special attention
IDynamicMetaObjectProvider
We know that any object that can have its operations bound at runtime must implement the IDynamicMetaObjectProvider. So is the Expando object.
Hence dynamic dyn = new ExpandoObject(); is a perfectly valid statement.
INotifyPropertyChanged
Whenever a new member is added or modified, the class raises the PropertyChange Event.
Let us now see how to return an anonymous collection from a method using Expando Object and then use it in LINQ query
Let us first fire up an windows application which will look as

Now let us prepare two xml files viz "Employee.xml" and "Department.xml" that will act as datasource.The file contents are as under
Employee.xml

Department.xml

Now let us write a method for reading the "Employee.xml" and store it in an Expando Object.
private List<ExpandoObject> GetEmpInformation()
{
var directoryPath = Environment.CurrentDirectory.Replace("\\bin\\Debug", "\\DataSource");
var filePath = Path.Combine(directoryPath, "Employee.xml");
try
{
//Load xml
XDocument xdoc = XDocument.Load(filePath);
if (xdoc == null) return null;
var empDetails = xdoc.Descendants("Employee")
.Select(empDetail =>
{
dynamic expandoObj = new ExpandoObject();
expandoObj.EmployeeId = Convert.ToInt32(empDetail.Attribute("Id").Value);
expandoObj.EmployeeName = empDetail.Attribute("Name").Value;
expandoObj.DepartmentCode = empDetail.Attribute("DepartmentCode").Value;
return (ExpandoObject)expandoObj;
}).ToList();
return empDetails;
}
catch (Exception ex)
{
throw ex;
}
}
First we are creating a new System.Xml.Linq.XDocument from the xml file usng the "Load" method of "XDocument" class.Then we are returning a filtered collection of the descendant elements(which is "Employee" here) for this document in document order.We are doing so by using the "Descendants" method of "XContainer" class.This class represents a node that can contain other nodes.
We are using the "Select" method for projecting each element of a sequence into a new form.Inside that we are first creating an "ExpandoObject". And then we are creating the properties of that on the fly and assigning the values.Finally returning the same.
A similar kind of implementation follows for reading the "Department.xml"
private List<ExpandoObject> GetDeptInformation()
{
var directoryPath = Environment.CurrentDirectory.Replace("\\bin\\Debug", "\\DataSource");
var filePath = Path.Combine(directoryPath, "Department.xml");
try
{
//Load xml
XDocument xdoc = XDocument.Load(filePath);
if (xdoc == null) return null;
var deptDetails = xdoc.Descendants("Department")
.Select(deptDetail =>
{
dynamic expandoObj = new ExpandoObject();
expandoObj.DepartmentCode = deptDetail.Attribute("DepartmentCode").Value;
expandoObj.DepartmentName = deptDetail.Attribute("Department").Value;
return (ExpandoObject)expandoObj;
}).ToList();
return deptDetails;
}
catch (Exception ex)
{
throw ex;
}
}
So now we have both the Employee and Department informations (collections) at our hand.The last step is to fire a JOIN using LINQ to find out the matching record.
List<ExpandoObject> EmpInformation = GetEmpInformation();
List<ExpandoObject> DeptInformation = GetDeptInformation();
//join between EmpInformation and DeptInformation
var recordSet = (
from emp in EmpInformation
join dept in DeptInformation on
(string)((IDictionary<string, object>)emp)["DepartmentCode"] equals
(string)((IDictionary<string, object>)dept)["DepartmentCode"]
select new
{
EmployeeId = (int)((IDictionary<string, object>)emp)["EmployeeId"],
EmployeeName = (string)((IDictionary<string, object>)emp)["EmployeeName"],
DepartmentCode = (string)((IDictionary<string, object>)dept)["DepartmentCode"],
DepartmentName = (string)((IDictionary<string, object>)dept)["DepartmentName"]
}).ToList();
ExpandoObject implements IDictionary<string, object>> interface for maintaining its list of members.The rest is pure join condition of Linq.
The final result is as under

References
ExpandoObject Class
Conclusion
So in this article we have seen as how Expando Object class has helped to return an anonymous collection from a method.Hope this will be useful.Zipped code is attached herewith.Thanks for reading.