c# - Cast<T> 的实现不是针对 Linq 的不可变风格吗?

标签 c# linq immutability

这就是Cast<T>在框架中实现:

public static IEnumerable<TResult> Cast<TResult>(this IEnumerable source)
{
    IEnumerable<TResult> enumerable = source as IEnumerable<TResult>;
    if (enumerable != null)
    {
        return enumerable; //the culprit
    }
    return Enumerable.CastIterator<TResult>(source);
}

我看到的问题是 Cast<T>如果满足某些条件,则返回实际可枚举本身。例如,这不应该发生:

var x = new List<string> { "1" };
var y = x.Cast<string>();

x.Add("2"); //reflects in y "immediately", since they are the same reference.

或者可能是一个更实际的例子:

object[] x = new[] { "1" };
var y = x.Cast<string>();

x[0] = "2"; //reflects in y "immediately", since they are the same reference.

The documentation page甚至说:此方法是通过使用延迟执行来实现的。,但并非在所有情况下都如此(如上所示)。同样我可以想到 AsEnumerable作为返回自身的另一个罪魁祸首。

可能跳闸的情况:

var x = new List<string> { "1" }; //data source
var y = x.Cast<string>(); //query


((List<string>)y).Add("2"); //did something with the query

// Whoa, got the data source itself changed by tinkering the query

问题:

  1. 不要这两个方法AsEnumerableCast违反 Linq 扩展方法的功能性质?可能是我错误地阅读了一些指南?

  2. System.Linq中是否有更多类似的扩展方法?返回自身的命名空间?


好吧,我想每个 linq 方法都会在枚举时产生一个新的序列,但这里不是这种情况。也许我不需要那样想。

但似乎对延期执行存在混淆。我预计对数据源的更改将反射(reflect)在 IEnumerable<T> 中仅在执行查询(我的意思是枚举)时由 linq 查询表示。例如,请考虑以下示例:

var x = new List<int> { 1 };
var y = x.Cast<SomeEnum>();

x.Add(2); //at this stage the change to x is not reflected in y yet

在上面的例子中,如果我添加一个新元素到x , y仍然指向一个查询,并且更改为 x未反射(reflect)在 y 中.我认为这是延迟执行,从某种意义上说,必须枚举它才能看到变化。与前面的示例一样,更改立即反射(reflect)在 y 中。 .所以我认为这不是真正的延期执行。从这里的答案来看,我的想法是错误的。

最佳答案

你给出的例子,操作源数组影响枚举的输出,实际上是由于延迟执行。所以他们并不表示延迟执行没有发生。

如果您获得对原始列表或 CastIterator 的引用,这没有区别。后者将懒惰地评估来源,因此两种情况都会反射(reflect)出变化。

如果 C# 是一种纯函数式语言,Linq 可能是惰性的(延迟的)并且会返回一个不会随时间改变的迭代。

但 C# 不是纯函数式语言。

Linq 团队不得不做出选择,并实现惰性部分。在 Linq 中实现不变性的成本更高。但是如果你想要不变性,你可以做到:只要停止更改源,或者在适当的时候使用 ToArray() 制作快照。

关于c# - Cast<T> 的实现不是针对 Linq 的不可变风格吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20317970/

相关文章:

performance - Coffeescript 中的自定义集合和可变性

c# - 如何在图中找到最长路径

c# - 按 NextObjectId 对对象列表进行排序

c# - 有没有办法找出将数据复制到剪贴板的源应用程序?

c# - 网络核心 : Find Data Type for any Variable Field in Class

java - Java 中的不可变集合

c# - 是否可以通过 F# 创建第三方可变结构 "more immutable"?

c# - 时间旅行调试 : How to do it in C#?

sql - 在 Entity Framework 中的两个模型的实体之间加入

c# - linq按子字符串对数组中的字符串进行排序