如何创建包含匿名对象的列表?

时间:2013-08-15 09:22:18

标签: c#

我创建了以下代码:

var header = "Entity Validation Error";
var detail = < I want to have a list that contains the title and errors list here>
foreach (var eve in ex.EntityValidationErrors)
{
    var title = string.Format("Entity of type \"{0}\" in state \"{1}\"
                has the following validation errors:",
        eve.Entry.Entity.GetType().Name, eve.Entry.State);
    System.Diagnostics.Debug.WriteLine(title);
    var errors = new List<string>();
    foreach (var ve in eve.ValidationErrors)
    {
        var error = string.Format("- Property: \"{0}\", Error: \"{1}\"",
            ve.PropertyName, ve.ErrorMessage);
        errors.Add(error);
        System.Diagnostics.Debug.WriteLine(error);
    }
}
return Request.CreateErrorResponse(HttpStatusCode.Conflict, 
         < I want to return the header and detail as an anonymous object >);

它会遍历我的每个实体错误,打印调试消息,创建标题和详细信息列表。

如何将变量标题和错误作为匿名对象并将其放入列表中以便我可以返回它们?

5 个答案:

答案 0 :(得分:6)

  

如何在C#中创建包含匿名对象的列表?

嗯,一种懒惰的方式是:object

var list = new List<object>();
//...
list.Add(new { Foo = 123, Bar = "abc" });
但是,这不是很有用。所以也许问题是“如何制作一个匿名类型的列表”;有点棘手 - 你需要使用一个实例来说服编译器注入T:

var list = Enumerable.Repeat(new { Foo = 123, Bar = "abc" }, 0).ToList();
//...
list.Add(new { Foo = 456, Bar = "def" });

(请注意,顶行中的列表为空;假实例只是编译器的模板)

但同样,这仍然是本地最好的。然后你说“我想要回归” - 现在那里就是真正有问题的地方。基本上,你不能返回它键入。您可以返回object或非通用IList - 但不是匿名类型,因此对调用者没有任何用处。

基本上,在这一点上我会说:“不要”。相反,创建常规类型,并将其作为公开。匿名类型在创建它们的方法之外不能很好地工作(有一些小的警告,比如数据绑定和序列化,没关系)。

答案 1 :(得分:1)

来自documentation

  

您不能声明字段,属性,事件或返回类型   具有匿名类型的方法。同样,你不能声明   方法,属性,构造函数或索引器的形式参数   有匿名类型。传递匿名类型或集合   包含匿名类型,作为方法的参数,您可以   将参数声明为类型对象。但是,做到这一点就失败了   强打字的目的。如果必须存储查询结果或传递它们   在方法边界之外,考虑使用普通的命名结构   或类而不是匿名类型。

这实际上总结了评论中所说的内容。如果你需要从方法中返回一些内容,那么它就是类接口的一部分。返回一个神秘的对象的界面对于它的客户端来说不是很清晰和可读,并且难以维护。

答案 2 :(得分:1)

这个怎么样:

public List<dynamic> GetAnonymousList()
{
   var list = new List<dynamic>()
    {
       new { Foo = 123, Bar = "abc" },
       new { Foo = 456, Bar = "def" }
    };

    return list;
}

在调用者中,您可以执行以下操作:

int fooSum = GetAnonymousList().Sum(item => item.Foo);
IEnumerable<string> bars = GetAnonymousList().Select(item => (string)item.Bar);

虽然这在实践中可能与返回List<object>然后使用Tomas Petricek描述的技巧将其强制转换回原始匿名类型一样糟糕:

http://tomasp.net/blog/cannot-return-anonymous-type-from-method.aspx

正如其他答案所说:如果你需要返回它,那么最好为项目定义一个合适的类型/接口。

答案 3 :(得分:0)

你可以做这样的事情

  public List<T> CreateList<T>(T itemOftype)
  {
     List<T> newList = new List<T>();
     return newList;
  } 

   var error = new { Header= "AVBC", Details = "Details" };
   var errorList = CreateList(error );

   errorList.Add(new { Header= "AVBC_BCGBD", Details = "Details_SBNJHJH" }

您还可以创建一个匿名对象数组并调用ToList()方法

答案 4 :(得分:0)

到目前为止,所有答案似乎都错过了你真正想要做的就是从看似很像JSON方法的东西中返回wep.api

但基于Request.CreateErrorResponse方法的重载列表(请参阅here),您似乎无法简单地从代码中返回您的匿名类型。

相反,您必须使用该方法的一个现有重载。也许你真的可以把它作为预先格式化的字符串返回,或者你可以尝试使用ModelStateDictionary重载(不确定它是否会起作用或者有多难)?

但是由于没有超载占用object(并且没有通用过载,而不是Request.CreateResponse),你无法完全按照自己的意愿行事。