Let's look at your function before making changes with resharper
public async Task<PaginationModel> LoadPaginationData() { IEnumerable<INode> nodes = _dleContent.QuerySelectorAll(".navi").First().QuerySelector("span.navigation") .ChildNodes.Where(node => node.NodeType != NodeType.Text); int currentPage = int.Parse(nodes .First(node => node.NodeName.Equals("SPAN") && !node.TextContent.Trim().Equals("...")) .TextContent); PaginationModel result = new PaginationModel { UpdateTime = DateTime.Now, PaginationData = nodes.ToDictionary( node => node.TextContent.Trim().Equals("...") ? -1 : int.Parse(node.TextContent), node => new Uri("http://example.com/")), CurrentPageId = currentPage }; return await Task.FromResult(result); }
Here you see that the variable nodes are reversed 2 times. And both of these times, since the variable nodes are an intangible enumeration, the enumeration will materialize. That is, the search for _dleContent in the code will occur twice.
But the code that offers resharper
public async Task<PaginationModel> LoadPaginationData() { IEnumerable<INode> nodes = _dleContent.QuerySelectorAll(".navi").First().QuerySelector("span.navigation") .ChildNodes.Where(node => node.NodeType != NodeType.Text); IEnumerable<INode> enumerable = nodes as INode[] ?? nodes.ToArray(); int currentPage = int.Parse(enumerable .First(node => node.NodeName.Equals("SPAN") && !node.TextContent.Trim().Equals("...")) .TextContent); PaginationModel result = new PaginationModel { UpdateTime = DateTime.Now, PaginationData = enumerable.ToDictionary( node => node.TextContent.Trim().Equals("...") ? -1 : int.Parse(node.TextContent), node => new Uri("http://example.com/")), CurrentPageId = currentPage }; return await Task.FromResult(result); }
As you can see, the call to the non-materialized transfer is only 1 time, and after the materialized result is stored in the enumerable variable, which is used later. That is, a search for _dleContent will occur only once, the search results will be remembered in an enumerable and reused.
As a matter of fact, instead of the additional variable, you could just materialize the listing immediately, for example
IEnumerable<INode> nodes = _dleContent.QuerySelectorAll(".navi").First().QuerySelector("span.navigation") .ChildNodes.Where(node => node.NodeType != NodeType.Text).ToArray();
As an example to understand, run the following code and look at the output
var nodes = Enumerable.Range(1, 10).Select(x => {Console.WriteLine(x); return x;}); var one = nodes.Where(x=>x%10==0).ToDictionary(x=>x,x=>x); var two = nodes.Where(x=>x%10==0).First();
Here we create 1 listing and materialize it 2 times. That is, the elements of the enumeration will be displayed in the console twice.
1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10