C# 如何判断扩展方法是否影响';这';还是不?
我知道字符串扩展方法返回一个字符串,实际上并不影响调用扩展方法的变量(因此它是不可变的)——但是我如何判断其他扩展方法是否会这样做呢?例如,我正在处理一个C# 如何判断扩展方法是否影响';这';还是不?,c#,.net,extension-methods,immutability,C#,.net,Extension Methods,Immutability,我知道字符串扩展方法返回一个字符串,实际上并不影响调用扩展方法的变量(因此它是不可变的)——但是我如何判断其他扩展方法是否会这样做呢?例如,我正在处理一个列表——我需要按日期降序排列此列表,因此我编写了以下代码: newsItems.OrderByDescending(o => o.Date); 这会影响新闻项列表还是只返回IORDerenumerable 换言之,上述代码实际应为: newsItems = newsItems.OrderByDescending(o => o.Da
列表
——我需要按日期降序排列此列表,因此我编写了以下代码:
newsItems.OrderByDescending(o => o.Date);
这会影响新闻项列表还是只返回IORDerenumerable
换言之,上述代码实际应为:
newsItems = newsItems.OrderByDescending(o => o.Date).ToList();
?
谢谢
Dan所有Linq扩展方法都只对序列执行查询操作,因此假设它们是只读的(查询)。因此,它们返回
IEnumerable
实例,这些实例提供表示操作结果的值序列
当然,没有什么可以阻止您创建一个扩展方法来修改应用它的对象(this
)
不过,API包含在这种情况下很有用的元数据。该属性可用于没有副作用的方法。如果您在IDE中使用诸如ReSharper之类的工具,那么当您尝试调用纯方法而不使用结果时,它将发出警告。因为这种方法是纯的,它在内存中的其他地方没有明显的副作用,所以忽略结果有点愚蠢。Linq运算符使用此属性进行注释。例如,它object.ToString()
。您也可以在自己的代码中使用此属性
tl;在这种情况下,R#博士会发现您的错误。是IEnumerable
上的扩展方法,它本身提供只读访问。当然,扩展方法可以强制转换到列表
,但基本上,LINQ到对象的扩展方法都不会影响它们的目标(当然,假设目标不受迭代的影响)
LINQ采用函数式设计——方法返回数据的新视图,而不是更改调用它们的目标
编辑:正如drew所指出的那样,[Pure]
属性可以用来表示这一点,一些工具会在其上找到它。然而:
- 您仍然需要相信
属性已正确应用[Pure]
- 判断是否存在
属性并不总是那么容易(例如,我链接到的文档中没有显示该属性)[Pure]
- 如果您对它的功能没有信心,那么您可能应该阅读文档以了解您调用的任何内容
DateTime DateTime.AddDays(int days)
,您将得到两个提示,表明该方法不会影响原始的DateTime-首先,DateTime是一个值类型,其次,它返回DateTime。如果在方法体中修改值类型,则它们的更改将仅在本地应用于堆栈上的副本。除非返回值类型,否则调用方永远无法观察到这些更改。相比之下,可以在调用方法中修改引用类型,并且调用方可以观察到这些修改
类似地,如果您有一个方法,例如IOrderedEnumerable OrderBy(IEnumerable enumerable)
,尽管输入类型是引用类型(并且可以修改),但提示是,当返回新类型时,原始类型将保持不变
最后,这可以通过测试得到证实。作为一般的关注点,LINQ方法链扩展方法都返回一个新的
IEnumerable
,是惰性计算的,并且不修改传入的内容IEnumerable
,相反,在返回的IEnumerable上调用GetEnumerator
时,应用一个过滤器进行计算。
您可以自己测试他,您知道。。。把3个数字放在一个列表中,看看它们是否被排序。我的问题是你怎么知道?每次我想知道扩展方法是否具有这种效果时,似乎没有必要运行这样的测试。字符串扩展方法无法更改字符串,因为字符串是不可变的。我知道,我在最初的帖子中确实提到了这一点。为什么有人投票结束这个问题?谢谢Jon。我现在碰巧知道了关于字符串的这一点,也知道了关于LINQ扩展的这一点——这只是一个经验案例(知道扩展做什么和不影响它们的目标),还是有一种方法可以通过查看扩展方法来判断???@DanielMcNulty:您阅读了文档,基本上,这里的扩展方法与其他方法没有什么不同。如果你要打电话,你应该了解它将要做什么,这通常包括阅读文档。非常感谢Jon,这就是我想要的——澄清一下这是否只是一个从经验和文档中知道我在使用什么的案例——公平是有意义的。再次感谢。@JonSkeet,Daniel的要求是可以通过正确的工具和PureAttribute
(在中解释)实现的。@DrewNoakes:在某些情况下,这会告诉我们,是的-但这并不总是显而易见的,即使在可能的情况下也不会总是被应用。将编辑。