• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

KeRNeLith / ImmediateReflection / 301

01 Oct 2025 07:29PM UTC coverage: 99.099% (-0.6%) from 99.738%
301

push

appveyor

KeRNeLith
Add a custom hashcode implementation on PropertyInfo usage as key for .NET targets as there is a regression on them.

See https://github.com/dotnet/runtime/issues/114280.

770 of 777 relevant lines covered (99.1%)

250.22 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

61.54
/src/ImmediateReflection/Helpers/ReflectionHelpers.cs
1
using System;
2
using System.Collections;
3
using System.Collections.Generic;
4
using System.Diagnostics;
5
using System.Reflection;
6
#if SUPPORTS_AGGRESSIVE_INLINING
7
using System.Runtime.CompilerServices;
8
#endif
9
using JetBrains.Annotations;
10

11
namespace ImmediateReflection.Utils
12
{
13
    /// <summary>
14
    /// Helpers to use C# reflection.
15
    /// </summary>
16
    internal static class ReflectionHelpers
17
    {
18
        /// <summary>
19
        /// Checks if the given parameter is a parameter using "params".
20
        /// </summary>
21
        /// <param name="param">A <see cref="ParameterInfo"/>.</param>
22
        /// <returns>True if the parameter correspond to a "params" parameter, false otherwise.</returns>
23
        [Pure]
24
        [ContractAnnotation("param:null => halt")]
25
        public static bool IsParams([NotNull] ParameterInfo param)
26
        {
27
            return param.IsDefined(typeof(ParamArrayAttribute), false);
32✔
28
        }
29

30
        /// <summary>
31
        /// Checks if the given <paramref name="property"/> is an indexed one.
32
        /// </summary>
33
        /// <param name="property">A <see cref="T:System.Reflection.PropertyInfo"/>.</param>
34
        /// <returns>True if the <paramref name="property"/> is an indexed property, false otherwise.</returns>
35
        [Pure]
36
        [ContractAnnotation("property:null => halt")]
37
        public static bool IsIndexed([NotNull] PropertyInfo property)
38
        {
39
            return property.GetIndexParameters().Length != 0;
1,969✔
40
        }
41

42
        /// <summary>
43
        /// Computes the hashcode for given <paramref name="property"/>.
44
        /// </summary>
45
        /// <param name="property">A <see cref="T:System.Reflection.PropertyInfo"/>.</param>
46
        /// <returns>A hashcode corresponding to <paramref name="property"/>.</returns>
47
        [Pure]
48
#if SUPPORTS_AGGRESSIVE_INLINING
49
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
50
#endif
51
        public static int GetPropertyInfoHashCode([NotNull] PropertyInfo property)
52
        {
53
#if !NETFRAMEWORK
54
            if (property.ReflectedType != null && property.DeclaringType != null)
55
                return HashCode.Combine(property.MetadataToken, property.DeclaringType.GetHashCode(), property.ReflectedType.GetHashCode());
56
#endif
57
            return property.GetHashCode();
3,900✔
58
        }
59

60
        /// <summary>
61
        /// <see cref="IEqualityComparer"/> implementation for <see cref="PropertyInfo"/>.
62
        /// </summary>
63
        /// <remarks>
64
        /// Overrides the default equality comparer for <see cref="PropertyInfo"/> since it has a drastic performance issue under NET5.0+ target.
65
        /// as described here: https://github.com/dotnet/runtime/issues/114280.
66
        /// </remarks>
67
        internal sealed class PropertyInfoEqualityComparer : IEqualityComparer, IEqualityComparer<PropertyInfo>
68
        {
69
            /// <inheritdoc />
70
            bool IEqualityComparer.Equals(object x, object y)
71
            {
72
                Debug.Assert(x != null);
73
                Debug.Assert(y != null);
74

75
                return Equals((PropertyInfo)x, (PropertyInfo)y);
×
76
            }
77

78
            /// <inheritdoc />
79
            int IEqualityComparer.GetHashCode(object obj)
80
            {
81
                return GetPropertyInfoHashCode((PropertyInfo)obj);
2,392✔
82
            }
83

84
            /// <inheritdoc />
85
            public bool Equals(PropertyInfo x, PropertyInfo y)
86
            {
87
                Debug.Assert(x != null);
88
                Debug.Assert(y != null);
89

90
                return x.Equals(y);
×
91
            }
92

93
            /// <inheritdoc />
94
            public int GetHashCode(PropertyInfo obj)
95
            {
96
                return GetPropertyInfoHashCode(obj);
×
97
            }
98
        }
99

100
        /// <summary>
101
        /// <see cref="IEqualityComparer"/> implementation for <see cref="MemberInfo"/>.
102
        /// </summary>
103
        /// <remarks>
104
        /// Overrides the default equality comparer for <see cref="PropertyInfo"/> (similarly to <see cref="PropertyInfoEqualityComparer"/>)
105
        /// since it has a drastic performance issue under NET5.0+ target as described here:
106
        /// https://github.com/dotnet/runtime/issues/114280.
107
        /// </remarks>
108
        internal sealed class MemberInfoEqualityComparer : IEqualityComparer, IEqualityComparer<MemberInfo>
109
        {
110
            /// <inheritdoc />
111
            bool IEqualityComparer.Equals(object x, object y)
112
            {
113
                Debug.Assert(x != null);
114
                Debug.Assert(y != null);
115

116
                return Equals((MemberInfo)x, (MemberInfo)y);
×
117
            }
118

119
            /// <inheritdoc />
120
            int IEqualityComparer.GetHashCode(object obj)
121
            {
122
                return GetHashCode((MemberInfo)obj);
3,166✔
123
            }
124

125
            /// <inheritdoc />
126
            public bool Equals(MemberInfo x, MemberInfo y)
127
            {
128
                Debug.Assert(x != null);
129
                Debug.Assert(y != null);
130

131
                return x.Equals(y);
×
132
            }
133

134
            /// <inheritdoc />
135
            public int GetHashCode(MemberInfo obj)
136
            {
137
                if (obj is PropertyInfo property)
3,166✔
138
                    return GetPropertyInfoHashCode(property);
1,508✔
139
                return obj.GetHashCode();
1,658✔
140
            }
141
        }
142
    }
143
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc