【问题标题】:Reset Boolean List重置布尔列表
【发布时间】:2015-02-16 17:40:30
【问题描述】:

我惊讶地发现下面的代码不起作用:

private List<bool> _IsSet = new List<bool>();
public void ClearIsSet()
{
    _IsSet.ForEach(x => x = false);
}

调用ClearIsSet 后,true 的值仍在列表中。

我知道我可以使用 for 循环使其工作。

有没有办法在没有for 循环的情况下完成这项工作?如果没有,为什么不呢?

编辑:

写完这个扩展函数,我没用过。

[Extension()]
public IList<T> ReplaceAll<T>(IList<T> Source, T Value)
{
    IList<T> Replacement = Source.Select(x => Value).ToList();
    Source.Clear();
    Source.AddRange(Replacement);
    return Source;
}

我刚用过:

_IsSet = _IsSet.Select(x => false).ToList()

因为Select 确实是ReplaceAll 在一个流畅的链中。

但是,你可以说:

_IsSet.ReplaceAll(false);

Select 无法做到这一点,但ReplaceAll 中的代码似乎很麻烦。

【问题讨论】:

    标签: .net generic-list


    【解决方案1】:

    foreach 循环为其迭代器变量创建一个本地副本,并为该副本分配一个新值。这不会改变列表中的元素。

    你可以使用

    _IsSet = Enumerable.Repeat(false, _IsSet.Count).ToList();
    

    或者如果你需要那个确切的列表实例:

    var count = _IsSet.Count;
    _IsSet.Clear();
    _IsSet.AddRange(Enumerable.Repeat(false, count));
    

    【讨论】:

    • 这与 i 是值类型无关;它也不适用于引用类型。这是因为 lambda 的参数是按值传递的,而不是按引用传递的。
    【解决方案2】:

    ForEach takes an Action and performs the Action on each item in the List.

    Action 不返回任何值。您在示例代码中所做的基本上是采用一个临时参数x,并将其分配给一个新值。这个变量x 只是从List 接收值;它不是对List 中的值的引用,因为bool 不是引用类型。为您的参数变量 x 分配一个新值不会影响原始列表值,就像您为代码中其他地方的方法参数分配一个新值一样。

    即使bool 是引用类型,ForEach 也不会将任何值分配回列表中的该位置。您可以更改 List 中的可变对象,但不能替换 List 中的值。

    您可能正在寻找的函数是IEnumerable&lt;T&gt;.Select。它接受一个从IEnumerable 的元素类型映射到某个新类型的函数,并返回一个包含转换后的元素的IEnumerable

    【讨论】:

    • 所以代码是_IsSet = _IsSet.Select(b =&gt; false)?
    • 其实_IsSet = _IsSet.Select(Function(x) False).ToList
    猜你喜欢
    • 2020-03-22
    • 1970-01-01
    • 2016-07-13
    • 1970-01-01
    • 2012-10-11
    • 2015-01-21
    • 2021-03-12
    • 2015-01-21
    相关资源
    最近更新 更多