Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 公开/传递要在私有列表上使用的LINQ表达式_C#_Linq - Fatal编程技术网

C# 公开/传递要在私有列表上使用的LINQ表达式

C# 公开/传递要在私有列表上使用的LINQ表达式,c#,linq,C#,Linq,我有一个私有列表,我想公开查询列表并返回包含新克隆项的新列表的功能。我可以传递代理进行过滤和排序,这很好,但是能够使用Linq表达式会更优雅 我已经添加了一个简单的例子来说明我正在尝试做什么,这可能会有所帮助,因为我认为我没有很好地解释我想要做什么 public class Repository { private List<SomeModel> _models; private object _lock; public List<SomeModel&

我有一个私有列表,我想公开查询列表并返回包含新克隆项的新列表的功能。我可以传递代理进行过滤和排序,这很好,但是能够使用Linq表达式会更优雅

我已经添加了一个简单的例子来说明我正在尝试做什么,这可能会有所帮助,因为我认为我没有很好地解释我想要做什么

public class Repository
{
    private List<SomeModel> _models;
    private object _lock;

    public List<SomeModel> GetModels(Func<SomeModel, bool> predicate)
    {
        List<SomeModel> models;
        lock (_lock)
        {
            models = _models.Where(m => predicate(m))
                            .Select(m => new SomeModel(m))
                            .ToList();
        }
        return models;
    }
}
公共类存储库
{
私有列表模型;
私有对象锁;
公共列表GetModels(Func谓词)
{
列出模型;
锁
{
models=_models.Where(m=>谓词(m))
.选择(m=>newsomemodel(m))
.ToList();
}
收益模型;
}
}

为什么您的代码涉及锁定?假设您的“SomeModel”类有一个副本构造函数,如您的示例所示,这应该是可行的:

public List<SomeModel> GetModels(Predicate<SomeModel> predicate)
{
    return _models.Where(m => predicate(m))
                  .Select(m => new SomeModel(m))
                  .ToList();
}
公共列表GetModels(谓词)
{
return _models.Where(m=>谓词(m))
.选择(m=>newsomemodel(m))
.ToList();
}

为什么您的代码涉及锁定?假设您的“SomeModel”类有一个副本构造函数,如您的示例所示,这应该是可行的:

public List<SomeModel> GetModels(Predicate<SomeModel> predicate)
{
    return _models.Where(m => predicate(m))
                  .Select(m => new SomeModel(m))
                  .ToList();
}
公共列表GetModels(谓词)
{
return _models.Where(m=>谓词(m))
.选择(m=>newsomemodel(m))
.ToList();
}

您可以通过如下操作将私有集合公开为迭代器块:

public IEnumerable<Model> Models
{
    get
    {
        foreach (Model mod in this._models)
            yield return new Model(mod);

        // equivalent to:
        // return _models.Select(m => new Model(m));
        // as per Jon's comment
    }
}
公共IEnumerable模型
{
得到
{
foreach(本款车型中的车型型号.\u车型)
新模型收益率(mod);
//相当于:
//返回_models.选择(m=>newmodel(m));
//根据乔恩的评论
}
}

这将使您能够像任何其他IEnumerable数据源一样针对它编写查询。

您可以通过以下操作将私有集合公开为迭代器块:

public IEnumerable<Model> Models
{
    get
    {
        foreach (Model mod in this._models)
            yield return new Model(mod);

        // equivalent to:
        // return _models.Select(m => new Model(m));
        // as per Jon's comment
    }
}
公共IEnumerable模型
{
得到
{
foreach(本款车型中的车型型号.\u车型)
新模型收益率(mod);
//相当于:
//返回_models.选择(m=>newmodel(m));
//根据乔恩的评论
}
}

这将使您能够像任何其他IEnumerable数据源一样针对它编写查询。

谢谢,当列表被另一个进程更新时,锁定就在那里(未显示,但这就是为什么我不能只公开列表)。是的,显示的SomeModel构造函数是一个复制构造函数。我还想应用排序和分页,所以我想要的不仅仅是谓词。我想应用一个Linq表达式。如果你想排序等(根据下面的答案),你最好不要返回一个列表,只返回Select子句。然后调用者可以将排序/分页逻辑应用于返回的IQueryable/IEnumerable.Good调用,这很有意义,可以很好地工作,我可能会真的这样做。但我会等待将此标记为已回答(大约一个小时),希望有人能够在锁外创建表达式并在锁内执行它。我认为mark@themissinglinq的答案是可接受的。我将对其进行编辑以反映Jon的评论。谢谢,当列表被另一个进程更新时,锁定就在那里(未显示,但这就是为什么我不能只公开列表)。是的,显示的SomeModel构造函数是一个复制构造函数。我还想应用排序和分页,所以我想要的不仅仅是谓词。我想应用一个Linq表达式。如果你想排序等(根据下面的答案),你最好不要返回一个列表,只返回Select子句。然后调用者可以将排序/分页逻辑应用于返回的IQueryable/IEnumerable.Good调用,这很有意义,可以很好地工作,我可能会真的这样做。但我会等待将此标记为已回答(大约一个小时),希望有人能够在锁外创建表达式并在锁内执行它。我认为mark@themissinglinq的答案是可接受的。我将编辑它以反映Jon的评论。aka return_models.Select(m=>newmodel(m));很好的回答,但我有一种感觉,从锁里面屈服是不好的。我会研究它,如果它能安全工作,我会很高兴地将此标记为答案?就我所见,由于返回类型IEnumerable和列表是可枚举的事实,只需执行
return\u模型会将其公开为可枚举项。。。(或者我遗漏了什么吗?)如果内部列表被同时修改,就不能使用yield,记住迭代器代码被延迟,直到迭代器被某人迭代。您需要创建数据的一个副本并返回useaimmutable list.aka return_models.Select(m=>newmodel(m));很好的回答,但我有一种感觉,从锁里面屈服是不好的。我会研究它,如果它能安全工作,我会很高兴地将此标记为答案?就我所见,由于返回类型IEnumerable和列表是可枚举的事实,只需执行
return\u模型会将其公开为可枚举项。。。(或者我遗漏了什么吗?)如果内部列表被同时修改,就不能使用yield,记住迭代器代码被延迟,直到迭代器被某人迭代。您需要创建数据的副本并返回使用不可变列表的副本。实际上,我希望传入一些Linq表达式,进行过滤、排序和分页,并在锁内执行类似“expression.Compile().Invoke(…)”的操作。问题#53597与我想做的类似。实际上,我希望传入一些Linq表达式,进行过滤、排序和分页,并在锁内执行类似于“expression.Compile().Invoke(…)”的操作。问题#53597与我想做的类似。