views:

1927

answers:

4

I've got a generic<> function that takes a linq query ('items') and enumerates through it adding additional properties. How can I select all the properties of the original 'item' rather than the item itself (as the code below does)?

So equivalent to the sql: select *, 'bar' as Foo from items

foreach (var item in items)
{
    var newItem = new {
     item, // I'd like just the properties here, not the 'item' object!
     Foo = "bar"
    };

    newItems.Add(newItem);
}
A: 
from item in items
where someConditionOnItem
select
{
     propertyOne,
     propertyTwo
};
Esteban Araya
Thanks, but the properties can't be hard-coded as 'item' is an anonymous type in a generic function
Nick
+3  A: 

There's no easy way of doing what you're suggesting, as all types in C# are strong-typed, even the anonymous ones like you're using. However it's not impossible to pull it off. To do it you would have to utilize reflection and emit your own assembly in memory, adding a new module and type that contains the specific properties you want. It's possible to obtain a list of properties from your anonymous item using:

foreach(PropertyInfo info in item.GetType().GetProperties())
    Console.WriteLine("{0} = {1}", info.Name, info.GetValue(item, null));
Kris
Cheers Kris, thought it would come down to reflection in the end..
Nick
+3  A: 

Shoot you wrote exactly what i was going to post. I was just getting some code ready :/

Its a little convoluted but anyways:

ClientCollection coll = new ClientCollection();
var results = coll.Select(c =>
{
    Dictionary<string, object> objlist = new Dictionary<string, object>();
    foreach (PropertyInfo pi in c.GetType().GetProperties())
    {
     objlist.Add(pi.Name, pi.GetValue(c, null));
    }
    return new { someproperty = 1, propertyValues = objlist };
});
mattlant
i re-edited the code to take out an inner select which was pointless
mattlant
just to explain, this does what was earlier posted, it adds the properties to a list on your newly generated items. Thats really the only way to automatically have all values.
mattlant
Thanks for the code Matt, off to cut and paste it in.. :)
Nick
A: 

Ask the item to give them to you.

Reflection is one way... however, since all the properties are known at compile time, each item could have a method that helps this query get what it needs.

Here's some example method signatures:

public XElement ToXElement()
public IEnumerable ToPropertyEnumerable()
public Dictionary<string, object> ToNameValuePairs()
David B