< Summary

Information
Class: MyNet.Primitives.ExpressionExtensions
Assembly: MyNet.Primitives
File(s): https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Primitives/Extensions/ExpressionExtensions.cs
Tag: 323_28699572109
Line coverage
92%
Covered lines: 24
Uncovered lines: 2
Coverable lines: 26
Total lines: 103
Line coverage: 92.3%
Branch coverage
63%
Covered branches: 14
Total branches: 22
Branch coverage: 63.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
IsSimilar(...)50%44100%
PropertyName(...)62.5%8891.66%
GetMembers(...)83.33%6688.88%
get_PropertyInfo(...)50%44100%

File(s)

https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Primitives/Extensions/ExpressionExtensions.cs

#LineLine coverage
 1// -----------------------------------------------------------------------
 2// <copyright file="ExpressionExtensions.cs" company="Stéphane ANDRE">
 3// Copyright (c) Stéphane ANDRE. All rights reserved.
 4// </copyright>
 5// -----------------------------------------------------------------------
 6
 7using System;
 8using System.Collections.Generic;
 9using System.Linq.Expressions;
 10using System.Reflection;
 11
 12#pragma warning disable IDE0130 // Namespace does not match folder structure
 13namespace MyNet.Primitives;
 14#pragma warning restore IDE0130 // Namespace does not match folder structure
 15
 16/// <summary>
 17/// Provides extension methods for working with expressions, particularly for extracting property paths from sorting exp
 18/// </summary>
 19public static class ExpressionExtensions
 20{
 21    extension(Expression? expression)
 22    {
 23        /// <summary>
 24        /// Determines whether two expressions are equal by comparing their string representations.
 25        /// </summary>
 26        /// <param name="b">The second expression to compare.</param>
 27        /// <returns>True if the expressions are similar; otherwise, false.</returns>
 628        public bool IsSimilar(Expression? b) => expression?.ToString() == b?.ToString();
 29    }
 30
 31    extension<T>(Expression<T> expression)
 32    {
 33        /// <summary>
 34        /// Extracts the property path from a sorting expression. The expression should be a simple member access (e.g.,
 35        /// </summary>
 36        /// <returns>The property path as a string.</returns>
 37        /// <exception cref="InvalidOperationException">Thrown when the expression is not a valid member access.</except
 38        public string PropertyName()
 39        {
 5440            var body = expression.Body;
 41
 5442            if (body is UnaryExpression { NodeType: ExpressionType.Convert } unary)
 043                body = unary.Operand;
 44
 5445            if (body is not MemberExpression memberExpression)
 346                throw new InvalidOperationException("Unable to infer sorting key from expression. Use a simple member ex
 47
 5148            var path = new Stack<string>();
 5149            Expression? current = memberExpression;
 50
 10551            while (current is MemberExpression currentMember)
 52            {
 5453                path.Push(currentMember.Member.Name);
 5454                current = currentMember.Expression;
 5455            }
 56
 5157            return string.Join('.', path);
 58        }
 59
 60        /// <summary>
 61        /// Gets the stack of MemberInfo objects representing the member access path in the given expression, which can 
 62        /// </summary>
 63        /// <returns>The stack of MemberInfo objects representing the member access path, or an empty stack if the expre
 64        public Stack<MemberInfo> GetMembers()
 65        {
 366            var stack = new Stack<MemberInfo>();
 367            var current = expression.Body;
 68
 969            while (current is not null)
 70            {
 971                if (current is MemberExpression member)
 72                {
 673                    stack.Push(member.Member);
 674                    current = member.Expression;
 75                }
 376                else if (current is UnaryExpression unary)
 77                {
 078                    current = unary.Operand;
 79                }
 80                else
 81                {
 82                    break;
 83                }
 84            }
 85
 386            return stack;
 87        }
 88    }
 89
 90    extension<T, TProperty>(Expression<Func<T, TProperty>> expression)
 91    {
 92        /// <summary>
 93        /// Gets PropertyInfo from a given expression that represents a property access. The expression should be a simp
 94        /// </summary>
 95        /// <returns>The PropertyInfo representing the property accessed by the expression.</returns>
 96        /// <exception cref="ArgumentException">Thrown when the expression is not a valid member access or the member is
 3397        public PropertyInfo PropertyInfo => expression.Body is not MemberExpression member
 3398            ? throw new InvalidOperationException("Expression must be a member access.")
 3399            : member.Member as PropertyInfo ?? throw new InvalidOperationException(
 33100                "Member is not a property.");
 101    }
 102}
 103