views:

117

answers:

8

When I do a query that returns an anonymous type

    var assets =
        from Product p in Session.CreateLinq<Product>()
        where bundles.Contains(p.ProductBundle)
        select new {p.Asset, p.Asset.PropertyTbl};

Can I type the return to anything other than var?

+4  A: 

You can use object or dynamic (in .NET 4.0) instead of var but don't expect to find a name to an anonymous type. In your case using var is better as it will preserve the strong typing at least until you leave the scope of the current method.

Darin Dimitrov
But in that case, var is better.
driis
@driis, absolutely
Darin Dimitrov
Note that by using `object` instead of `var` there will be no intellisense for the properties.
Fredrik Mörk
A: 

No, since you are creating a new anonymous type (except of object, of course). Your only way to get around this is to define a new Class or Structure with accordingly properties/fields

dkson
+5  A: 

You cannot* return an anonymous type because the caller would not know what type it is and wouldn't be able to use it.

If you want to return the results, you can create objects of a non-anonymous type:

IEnumerable<Foo> assets =
    from Product p in Session.CreateLinq<Product>()
    where bundles.Contains(p.ProductBundle)
    select new Foo { Bar = p.Asset, Baz = p.Asset.PropertyTbl};

You can also use the Tuple type in .NET 4 if you don't want to create a custom class for your values.


* This is not strictly true - it is possible but you should avoid doing it. Here is a link anyway if you really want to.

Mark Byers
Thanks for the clarification. I haven't come across Tuple yet, will have to check into it.
Mike Q
A: 

Not really. If you cast to object you wont be able to access the properties of your anonymous class.

The var keyword was specifically introduced for dealing with anonymous classes - why would you want to avoid it? If you need to return the data you should name the class.

Janus Tøndering
+1  A: 

You could define a new class:

public class AssetProp
{
   public virtual string Asset {get;set;}
   public virtual string PropertyTbl {get;set;}
}

And then you can return it as that class:

IEnumerable<AssetProp> assets =
    from Product p in Session.CreateLinq<Product>()
    where bundles.Contains(p.ProductBundle)
    select new AssetProp {p.Asset, p.Asset.PropertyTbl};
GenericTypeTea
A: 

Not really, since the new {p.Asset, p.Asset.PropertyTbl} code creates an anonymous type. Even using object doesn't really gain you much since you can't cast it to anything useful later on, so you would have to use reflection to access the properties.

corvuscorax
A: 

You can if you use lambda expressions, otherwise you can do a cast but do some good exception handling.

Nealv
A: 

you can also do this (it does relate much to your problem though, because you just move "var" somewhere else, but it's interesting that it recognize those types as same)

        var element = new { id = 7 };

        List<object> collection = new List<object>();
        element = collection.Select(item => new { id = 0 }).First();
Kikaimaru