【问题标题】:How to handle return of List<AnonymousType>? [duplicate]如何处理 List<AnonymousType> 的返回? [复制]
【发布时间】:2011-11-21 14:49:25
【问题描述】:

可能重复:
LINQ to SQL: Return anonymous type?

这是我的代码:

 class B
    {
        public int age { get; set; }
        public string name { get; set; }
    }

    class Program
    {
        static List<whatshouldIwritehere> GetList()
        {
            List<B> list = new List<B>() {
                new B(){ age = 10, name = "jaagu" },
                new B(){ age = 20, name = "juggu" },
                new B(){ age = 30, name = "jockey" },
                new B(){ age = 40, name = "jaggu" },
            };

            return (from item in list
                select new { MyAge = item.age, MyName = item.name }).ToList();
        }

        static void Main(string[] args)
        {

            Console.Read();
        }
    }

谁能告诉我函数GetList()的返回类型应该写什么?我知道查询创建了一个匿名类,我想跨函数使用该类。如果我使用 MyAge 和 MyName 创建一个自定义类,那么很容易在返回类型中给出它。但是,还有其他出路吗?如果这是在同一个函数中,我会使用 var 关键字。但我不能在这里使用它。

【问题讨论】:

  • 岩石和坚硬的地方。你想命名一个匿名类型。这不会发生。
  • 为什么要返回匿名类型?
  • 这是匿名类型的一般限制。由于它们没有命名,因此它们不能以需要主名的良好类型方式暴露在任何地方。希望链接的答案能提供一些见解。
  • @everyone:阅读 Petar Ivanov 的回答,虽然没有编译时支持,但它会完美运行。但比使用反射或创建大量“类重载”要好得多

标签: c# linq anonymous-types


【解决方案1】:

您可以返回List&lt;object&gt;List&lt;dynamic&gt;

如果您返回object,那么您将无法访问属性,除非使用反射。 如果返回动态,则可以访问属性,但会丢失编译时检查。 (因此,属性名称中的拼写错误将导致运行时异常)。

编辑: 您需要为 ToList 函数明确指定类型:

    static List<dynamic> GetList()
    {
        List<B> list = new List<B>() {
            new B(){ age = 10, name = "jaagu" },
            new B(){ age = 20, name = "juggu" },
            new B(){ age = 30, name = "jockey" },
            new B(){ age = 40, name = "jaggu" },
        };

        return (from item in list
                select new { MyAge = item.age, MyName = item.name }).ToList<dynamic>();
    }

【讨论】:

  • dynamic 在我的情况下可以完美运行,但在编译过程中出现此错误:“错误 1 ​​无法将类型 'System.Collections.Generic.List' 隐式转换为 'System.Collections。 Generic.List'"。我不想使用对象。使用对象意味着当我尝试访问属性时,我将不得不使用反射。
  • 这些选项似乎都不怎么好吃。
  • 完美!谢谢皮塔尔。你没有像 BoltClock 那样交叉质疑我为什么要这样做,而是给了我一个完美的答案。
  • @Jaggu 我原以为你会欣赏像 BoltClock 这样的高级用户的明智建议。
  • 指定类型:.ToList()
【解决方案2】:

你可以这样做。重用 B 类,而不是创建匿名类。

    static List<B> GetList() 
            { 
....
         return (from item in list 
                    select new B(){age = item.age, name = item.name }).ToList(); 
}

【讨论】:

  • B 没有 MyAge 和 MyName。它只有年龄和名字。
  • 使用年龄和姓名;我已经更新了。您是否特别关注 MyAge 和 MyName 这两个名字?只需重命名它
  • +1;注意:我引用(偷了)你的答案,并提供了一些理由来配合它。这个答案没有解决机械问题(我如何返回匿名类型?),但它确实为代码示例提供了正确的答案。
【解决方案3】:

坦率地说,如果您不想重用 B,那么您应该定义一个新类型或使用另一个现有类型来保存您的数据(例如元组)。

匿名类型没有名称,并且您在编译时没有任何真实的类型信息,因此您无法从函数中返回它们。 “修补”您的方法以返回dynamicobject 的列表就是这样,一个补丁。对于这两个选项,它总是不是最理想的,您将不得不求助于使用反射(直接和间接)。

【讨论】:

    【解决方案4】:

    使用dynamicobject

    As Peter mentioned,您可以使用objectdynamic。为此,请在调用 ToList 之前添加一个演员表,这样您就可以指定要返回的列表类型:

    return (from item in list
            select (dynamic)new { MyAge = item.age, MyName = item.name })
        .ToList();
    

    或者:

    return (from item in list
            select new { MyAge = item.age, MyName = item.name })
        .Cast<dynamic>()
        .ToList();
    

    编辑:

    其实他的ToList&lt;dynamic&gt;() 更好看。但是请继续阅读,我认为对于您给出的示例来说,这仍然不是一个好的解决方案......

    重用 B

    相反,As Sandeep mentioned,您可以重复使用 B

    在我看来,这是正确的做法。您应该遵循与面向对象编程一致的命名约定。对象的属性名称在实例中立时最有意义,而“My”不是实例中立。

    改为将您的实例命名为my

    foreach(B my in GetList())
    {
        Console.WriteLine(my.age);
        Console.WriteLine(my.name);
    }
    

    【讨论】:

    • 请不要在未解释原因的情况下投反对票。我不只是警察回答 - 我添加了理由。此外,在我发布此内容时,Peter 没有工作示例。
    猜你喜欢
    • 1970-01-01
    • 2021-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-29
    • 1970-01-01
    • 2020-05-01
    • 2016-01-04
    相关资源
    最近更新 更多