How to determine if an extension method affects 'this' or not?

I know that String extension methods return String and do not actually affect the variable that calls the extension method (therefore it is immutable), but how can I determine if other extension methods do or not? For example, I work with List<NewsItem> - and I need to order this list in descending order, so I wrote this code:

 newsItems.OrderByDescending(o => o.Date); 

Does this affect the list of newsItems or just returns IOrderedEnumerable ??

In other words, should the above code really read:

 newsItems = newsItems.OrderByDescending(o => o.Date).ToList(); 

??

Thanks,

Dan

+4
source share
3 answers

OrderByDescending is an extension method on IEnumerable<T> , which itself provides read-only access. Of course, the extension method can be applied to List<T> , but basically none of the extension methods LINQ to Objects affects their purpose (provided, of course, that the goals are not subject to iteration).

LINQ is designed in a functional style - methods return a new kind of data, rather than changing the purpose for which they are called.

EDIT: As indicated in the figure, the [Pure] attribute can be used as an indication of this, and some tools will be typed on it. But:

  • You still need to believe that the [Pure] attribute has been correctly applied.
  • It is not always easy to determine if the [Pure] attribute is (it does not appear in the documents to which I am attached, for example)
  • You should probably read the documentation for any reason if you are not sure what it is doing.
+4
source

All Linq extension methods only perform query operations on sequences, so suppose they are read-only (queries). Thus, they return instances of IEnumerable<T> that provide sequences of values ​​representing the result of the operation.

Of course, nothing prevents you from creating an extension method that modifies the object to which it has applied ( this ).

The API contains metadata that are useful in this case. The PureAttribute attribute can be used for a method that has no side effects. If you use a tool like ReSharper in your IDE, it will warn you when you try to call a clean method and don’t use the result. Since this method is pure, it has no visible side effects elsewhere in the memory, so ignoring the result is a bit silly. Linq operators are annotated with this attribute. So this is object.ToString() , for example. You can also use this attribute for your own code.

tl; dr R # would find your mistake in this case.

+2
source

Usually by parameter (value type or reference type), and secondly, by return type.

If you have a method signature, such DateTime DateTime.AddDays(int days) , you get two hints that the method does not affect the original datetime - firstly, that DateTime is a value type, and secondly, it returns DateTime. Value types, if changed in the method body, will have their own changes applied locally to the copy on the stack. If the value type is not returned, the caller will not be able to make these changes. The types of links in contrast can be changed in the calling method and have changes observed by the caller.

Similarly, if you have a method like IOrderedEnumerable<T> OrderBy(IEnumerable<T> enumerable) , even though the input type is a reference type (and can be changed), the hint is that when you return a new type the original will remain unchanged.

Finally, this can be confirmed by testing. As a common point of interest, LINQ method chain extension methods return a new IEnumerable<T> , lazily evaluate and do not change the contents of the IEnumerable<T> passed in, instead using the filter that evaluates when GetEnumerator called, the IEnumerable<T>. returned IEnumerable<T>.

0
source

Source: https://habr.com/ru/post/1392021/


All Articles