将元素添加到IEnumerable <ipublishedcontent>

时间:2016-10-05 06:30:24

标签: c# asp.net linq generics

我有两个IEnumerable对象,如果满足特定条件,我需要将每个元素从第一个IEnumerable带到第二个IEnumerable。我的代码就像这样

IEnumerable<IPublishedContent> nodesTemp = posts.Take(10).ToList();
IEnumerable<IPublishedContent> nodes = null;
foreach (var n in nodesTemp)
{
    if (condition=true)
    {
        nodes.add(n);           
    }
}

但这会引发错误

  

:&#39; System.Collections.Generic.IEnumerable&lt; Umbraco.Core.Models.IPublishedContent&gt;&#39;不包含&#39;添加&#39;的定义没有扩展方法&#39;添加&#39;接受类型&#39; System.Collections.Generic.IEnumerable&lt; Umbraco.Core.Models.IPublishedContent&gt;&#39;的第一个参数。可以找到(你错过了使用指令或程序集引用吗?)

     

完整的参考代码

 IEnumerable<IPublishedContent> nodesTemp = posts.Take(count).ToList();

IEnumerable<IPublishedContent> nodes = null;
foreach (IPublishedContent n in nodesTemp)
{
    var rolename = n.GetProperty("focusedUserGroup").Value.ToString();
    var username = umbraco.cms.businesslogic.member.Member.GetCurrentMember().Text;
    var flag = false;

    if (!string.IsNullOrEmpty(rolename))
    {
        var groups = rolename.Split(',');

        foreach (var group in groups)
        {
            if (Roles.IsUserInRole(username, group))
            {
                nodes.add(n);
                break;
            }
        }

    }
}

3 个答案:

答案 0 :(得分:4)

你不能这样做。原因是因为IEnumerable只是代表某些集合的迭代器。它可以是内存中的数组,从远程数据库中选择,甚至是这样的常量调用:

AuditEntity

您可以做的是扩展第一个集合的post iterator。例如:

IEnumerable<int> GetSomeConsts()
{
    yield return 1;
    yield return 101;
    yield return 22;
}

然后就这样称呼它:

bool IsCondition(IPublishedContent n)
{
    var rolename = n.GetProperty("focusedUserGroup").Value.ToString();
    var username = umbraco.cms.businesslogic.member.Member.GetCurrentMember().Text;

    if (!string.IsNullOrEmpty(rolename))
    {
        var groups = rolename.Split(',');

        foreach (var group in groups)
        {
            if (Roles.IsUserInRole(username, group))
            {
                 return true;
            }
        }
    }
    return false;
}

答案 1 :(得分:1)

我认为这是你可以使用

的收益率回报的一个很好的例子

例如:

public IEnumerable<IPublishedContent> Whatever(IEnmerable<IPublishedContent> nodes, int count)
{
    foreach(var node in nodes.Take(count))
    {
        var rolename = node.GetProperty("focusedUserGroup").Value.ToString();
        var username = umbraco.cms.businesslogic.member.Member.GetCurrentMember().Text;
        if (!string.IsNullOrEmpty(rolename))
        {
            var groups = rolename.Split(',');

            foreach (var group in groups)
            {
                if (Roles.IsUserInRole(username, group))
                {
                     yield return node; //yield return allows you to create a new enumerable inline
                     break;
                }
            }
        }
    }
}

yield return会在你枚举时执行你的代码,所以如果你要调用Whatever(...)。First()它只会运行代码,直到它找到第一个yield return。

答案 2 :(得分:0)

看起来你正在过滤IEnumerable。

在这种情况下,您无需先将其转换为列表,也可以使用Enumerable<T>.Where()对其进行过滤。

这样的事情应该有效:

var nodesTemp = posts.Take(10);
var nodes = nodesTemp.Where(item => predicate(item));

predicate(item)是某个函数,它接受IPublishedContent类型的参数并返回bool

您可以将其写为lambda表达式,例如:

var nodesTemp = posts.Take(10);
var nodes = nodesTemp.Where(item => item.SomeProperty == someTargetValue);

如果您需要nodes作为列表而不是IEnumerable<IPublishedContent>,则可以将其转换为列表:

var nodes = nodesTemp.Where(item => item.SomeProperty == someTargetValue).ToList();

此时您可能并不真正需要nodesTemp(除非您将其用于调试目的):

var nodes = 
    posts.Take(10)
    .Where(item => item.SomeProperty == someTargetValue)
    .ToList();