简体   繁体   中英

Returning collection of anonymous types in C#

I have a VS2010 solution consisting of two projects - a "data" project and a webservice project that consumes the data project. In order to protect from exposing the schema of the database I've opted to return anonymous (var) objects to the consumer of the webservice. My question is, some of what I return will be in collections. So instead of using this code to return a single anonymous object:

var item = from w in db.Widgets
    where w.widget_id == 1
    select new {
        name = w.name, 
        address = w.address
    };

I would want to use something similar to this to return a collection.

IQueryable<var> item = (from w in db.Widgets
        where w.widget_id == 1
        select new {
            name = w.name, 
            address = w.address
        }).IQueryable;

I realize this is not the exact way to do this ... just need to know how it would really be done.

Thanks!

Anonymous types themselves cannot be exposed outside of their declaring function, so the only way to expose an instance of an anonymous type outside of the declaring function is as an object . If you need to do this, you'll have to declare a type at a higher scope with the properties that you need, then hydrate it within your query rather than the anonymous type.

Instead of returning anonymous types, I'd have a strong typed layer that is returned. It can still be filled from the database in whichever way you want and you'd have a strong contract for the consumer of the service. The consumer won't even know there is a database, it could just as well be xml.

You could, in theory, do this:

public List<object> GetObjects()
{
    return (from w in db.Widgets
        where w.widget_id == 1
        select (object) new {
            name = w.name, 
            address = w.address
        }).ToList();
}

However, I don't understand why you want to do this — the caller will obviously not be able to make any use of your anonymous type, except via Reflection or other hacky stuff. Why not simply return a normal class that everyone can use normally?

public class NameAndAddress
{
    public string Name { get; private set; }
    public string Address { get; private set; }
    public NameAndAddress(string name, string address)
    {
        Name = name;
        Address = address;
    }
}

public List<NameAndAddress> GetObjects()
{
    return (from w in db.Widgets
        where w.widget_id == 1
        select new NameAndAddress(w.name, w.address)
    ).ToList();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM