| File: MemberExpressionCacheKey.cs | Web Access |
| Project: src\aspnetcore\src\Mvc\Mvc.ViewFeatures\src\Microsoft.AspNetCore.Mvc.ViewFeatures.csproj (Microsoft.AspNetCore.Mvc.ViewFeatures) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Linq.Expressions; using System.Reflection; namespace Microsoft.AspNetCore.Mvc.ViewFeatures; internal readonly struct MemberExpressionCacheKey { public MemberExpressionCacheKey(Type modelType, MemberExpression memberExpression) { ModelType = modelType; MemberExpression = memberExpression; Members = null; } public MemberExpressionCacheKey(Type modelType, MemberInfo[] members) { ModelType = modelType; Members = members; MemberExpression = null; } // We want to avoid caching a MemberExpression since it has references to other instances in the expression tree. // We instead store it as a series of MemberInfo items that comprise of the MemberExpression going from right-most // expression to left. public MemberExpressionCacheKey MakeCacheable() { var members = new List<MemberInfo>(); foreach (var member in this) { members.Add(member); } return new MemberExpressionCacheKey(ModelType, members.ToArray()); } public MemberExpression MemberExpression { get; } public Type ModelType { get; } public MemberInfo[] Members { get; } public Enumerator GetEnumerator() => new Enumerator(this); public struct Enumerator { private readonly MemberInfo[] _members; private int _index; private MemberExpression _memberExpression; public Enumerator(in MemberExpressionCacheKey key) { Current = null; _members = key.Members; _memberExpression = key.MemberExpression; _index = -1; } public MemberInfo Current { get; private set; } public bool MoveNext() { if (_members != null) { _index++; if (_index >= _members.Length) { return false; } Current = _members[_index]; return true; } if (_memberExpression == null) { return false; } Current = _memberExpression.Member; _memberExpression = _memberExpression.Expression as MemberExpression; return true; } } }