这个 Linq 查询可以输入为“var”以外的任何内容吗?

Posted

技术标签:

【中文标题】这个 Linq 查询可以输入为“var”以外的任何内容吗?【英文标题】:Can this Linq query be typed as anything other than "var"? 【发布时间】:2011-03-21 11:48:33 【问题描述】:

当我执行返回匿名类型的查询时

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

我可以输入除 var 以外的任何返回值吗?

【问题讨论】:

为什么要使用其他类型?你想解决什么问题? 【参考方案1】:

你不能*返回一个匿名类型,因为调用者不知道它是什么类型并且不能使用它。

如果要返回结果,可以创建非匿名类型的对象:

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;

如果您不想为您的值创建自定义类,也可以在 .NET 4 中使用 Tuple 类型。


* 严格来说这不是真的 - 有可能,但您应该避免这样做。如果你真的想的话,这里是link。

【讨论】:

感谢您的澄清。我还没有遇到元组,必须检查一下。【参考方案2】:

您可以使用objectdynamic(在.NET 4.0 中)代替var,但不要期望找到匿名类型的名称。在您的情况下,使用 var 更好,因为它至少会保留强类型,直到您离开当前方法的范围。

【讨论】:

但在这种情况下,var 更好。 请注意,使用object 而不是var 将不会对属性进行智能感知。【参考方案3】:

你可以定义一个新的类:

public class AssetProp

   public virtual string Asset get;set;
   public virtual string PropertyTbl get;set;

然后你可以将它作为那个类返回:

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

【讨论】:

【参考方案4】:

并非如此,因为new p.Asset, p.Asset.PropertyTbl 代码创建了一个匿名类型。即使使用object 也不会真正为您带来太多好处,因为您以后无法将其转换为任何有用的东西,因此您必须使用反射来访问属性。

【讨论】:

【参考方案5】:

不是真的。如果您强制转换为对象,您将无法访问匿名类的属性。

var 关键字是专门为处理匿名类而引入的——为什么要避免它?如果你需要返回数据,你应该命名类。

【讨论】:

【参考方案6】:

如果你使用lambda expressions,你可以,否则你可以做一个演员,但做一些好的异常处理。

【讨论】:

【参考方案7】:

您也可以这样做(虽然它确实与您的问题有很大关系,因为您只是将“var”移动到其他地方,但有趣的是它会将这些类型识别为相同)

        var element = new  id = 7 ;

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

【讨论】:

以上是关于这个 Linq 查询可以输入为“var”以外的任何内容吗?的主要内容,如果未能解决你的问题,请参考以下文章

FirstOrDefault:除 null 以外的默认值

重用 LINQ 查询

减少用于过滤的 linq 查询

如何从字符串创建 LINQ 查询?

具有XPath查询的SQL到LINQ转换

使用 var、动态和 linq 组合的奇怪行为变化