Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.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# 如何判断扩展方法是否影响';这';还是不?_C#_.net_Extension Methods_Immutability - Fatal编程技术网

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:在某些情况下,这会告诉我们,是的-但这并不总是显而易见的,即使在可能的情况下也不会总是被应用。将编辑。