C# 向IEnumerable添加项

C# 向IEnumerable添加项,c#,ienumerable,C#,Ienumerable,我有一个对象列表,但现在需要将其更改为IEnumerable。所以,我有这个: public IEnumerable<TransactionSplitLine> TransactionSplitLines { get; set; } 现在应该如何添加项目?没有Add(t)方法。根据您的真实类型,您可以按以下方式进行施放: var item = new TransactionSplitLine {Amount = "100", Category = "Test", SubCatego

我有一个对象列表,但现在需要将其更改为IEnumerable。所以,我有这个:

public IEnumerable<TransactionSplitLine> TransactionSplitLines { get; set; }
现在应该如何添加项目?

没有
Add(t)
方法。根据您的真实类型,您可以按以下方式进行施放:

var item = new TransactionSplitLine {Amount = "100", Category = "Test", SubCategory = "Test More", CategoryId=int.Parse(c)};

((IList)reply.TransactionSplitLines).Add(item);
private List<TransactionSplitLine> transactionSplitLines;

public IEnumerable<TransactionSplitLine> TransactionSplitLines 
{ 
  get
  {
     return transactionSplitLines;
  }
}
如果您正在使用的集合实现了IList

请记住,在传递对象时要使用最基本的接口/类。因此,如果您需要使用
IList
中的方法,我建议您使用它而不是
IEnumerable

我建议您进行以下更改:

public IList<TransactionSplitLine> TransactionSplitLines { get; set; }
public IList TransactionSplitLines{get;set;}

您无法将项目添加到
IEnumerable
,因为此界面没有
add
方法。
如果
TransactionSplitLines
始终返回
列表的实例
,则可能需要将其类型更改为
IList

如果您无法更改
TransactionSplitLines
的类型,并且您可以保证它始终返回
IList
,您可以将其转换为

((IList<TransactionSplitLine>)reply.TransactionSplitLines).Add(new TransactionSplitLine
                                                    {Amount = "100", Category = "Test", SubCategory = "Test More", CategoryId=int.Parse(c)});
((IList)reply.TransactionSplitLine)。添加(新TransactionSplitLine)
{Amount=“100”,Category=“Test”,SubCategory=“Test More”,CategoryId=int.Parse(c)};

这取决于您的
TransactionSplitLines
属性的含义和用途

如果您希望允许从类外部进行编辑(添加/删除),那么只需使您的属性不象
IEnumerable
那样通用即可,例如:

public IList<TransactionSplitLine> TransactionSplitLines { get; set; }
public IList TransactionSplitLines{get;set;}
或者更好:

public ICollection<TransactionSplitLine> TransactionSplitLines { get; set; }
public ICollection TransactionSplitLines{get;set;}

相反,如果您只需要在内部编辑集合(我的意思是在类范围内),为什么不这样做:

var item = new TransactionSplitLine {Amount = "100", Category = "Test", SubCategory = "Test More", CategoryId=int.Parse(c)};

((IList)reply.TransactionSplitLines).Add(item);
private List<TransactionSplitLine> transactionSplitLines;

public IEnumerable<TransactionSplitLine> TransactionSplitLines 
{ 
  get
  {
     return transactionSplitLines;
  }
}
private List transactionSplitLines;
公共IEnumerable事务分割线
{ 
得到
{
返回交易分界线;
}
}

因此,您可以使用
transactionSplitLines
字段在内部更改集合

您可以使用Concat执行以下操作:

reply.TransactionSplitLines = 
    reply.TransactionSplitLines.Concat(new []{new TransactionSplitLine                                                     {
                                                 Amount = "100", 
                                                 Category = "Test", 
                                                 SubCategory = "Test More",
                                                 CategoryId = int.Parse(c)}});
这基本上创建了一个新的
IEnumerable
。在您的案例中很难说什么是最好的解决方案,因为关于您的用例没有足够的信息

编辑:
请注意,
List
实现了
IEnumerable
。因此,如果您需要传递一个
IEnumerable
作为参数,例如,您也可以传递一个
List
,可以先在列表上显式调用。因此,也许您可以坚持使用列表而不是IEnumerable。

您可以使用
Concat
方法连接两个集合,如下所示:

reply.TransactionSplitlines = reply.TransactionSplitlines.Concat(/* another enumerable */);
您需要编写一个扩展方法
AsEnumerable
,它将接受一个
obj
,并执行类似于
yield return obj的操作。您可以避免编写扩展方法,只需将包含对象的
new[]
传递给
Concat
方法,但如果您的接口基于
IEnumerable
,则在其他一些情况下,您可能也需要
AsEnumerable
方法


如果你真的需要它是
IEnumerable
。但是,我建议考虑切换到<代码> IIST < /COD>或其他支持<代码> Addio>代码>的其他接口。如果需要通过使用
IEnumerable
属性来实现某个接口,则可以将
IList
作为该属性的内部字段,并单独修改它-很可能是在这里使用的是具体对象,而不是接口。如果您正在使用该界面,并且仍然需要使用
Add
IEnumerable
对于该界面来说是一个糟糕的类型选择。

简短回答:您不能将项添加到
IEnumerable

稍长的解释:

IEnumerable
是一个接口,它只关心能够枚举/迭代项集合。这是存在
IEnumerable
的唯一目的。它抽象了存储或检索可枚举项的方式的任何概念(可能是字符串、项列表、字节流或一系列计算结果),因此,如果您有一个接口是
IEnumerable
,则无法向其添加项,只能对其提供的项进行迭代

也就是说,向
IEnumerable
添加项目的正确方法是返回新的
IEnumerable
,并将新项目附加到原始内容中

此外,使用Linq库,您还有一个扩展方法,允许通过
IEnumerable.ToList()
将IEnumerable强制转换为列表,并可以向列表中添加项。但这不是正确的方法

使用命名空间中的Linq库,您可以执行以下操作:

using System;
using System.Collections.Generic;
using System.Linq;

namespace EnumTester
{
    class Program
    {
        static void Main(string[] args)
        {
             IEnumerable<string> enum = GetObjectEnumerable();

             IEnumerable<string> concatenated = enum.Concat(new List<string> { "concatenated" });

             List<string> stringList = concatenated.ToList();
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
命名空间枚举测试器
{
班级计划
{
静态void Main(字符串[]参数)
{
IEnumerable enum=GetObjectEnumerable();
IEnumerable concatenated=enum.Concat(新列表{“concatenated”});
List stringList=连接的.ToList();
}
}
}

我将创建这个扩展方法,它可以懒洋洋地完成所有这些工作:

public static IEnumerable<T> Append<T>(this IEnumerable<T> source, params T[] items)
{
    return source.Concat(items);
}
您还可以使用
Prepend
,类似地:

public static IEnumerable<T> Prepend<T>(this IEnumerable<T> source, params T[] items)
{
    return items.Concat(source);
}
公共静态IEnumerable前置词(此IEnumerable源,参数T[]项)
{
返回项目。Concat(来源);
}

IEnumerable是不可变的集合,这意味着您无法添加或删除项。扩展方法创建一个新实例。(这里用一个示例解释:) 相反,在创建扩展方法之后,可以先将其添加到列表中,如下所示: 例如,在我的例子中,用户角色被定义为IEnumerable(在User mod中)
List<Role> rols=new List<Role>();
foreach(int i=0;i<chkRoles.count;i++)
{
 Role r=new Role();
r.RoleId="2";
r.RoleName="Admin";
rols.add(r);
}
user.Roles=rols.AsEnumerable();