Skip to content

Commit c25c3a3

Browse files
authored
Update PredefinedMethodsHelper
1 parent 95dda78 commit c25c3a3

File tree

2 files changed

+67
-15
lines changed

2 files changed

+67
-15
lines changed

src/System.Linq.Dynamic.Core/DynamicClassFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ private static Type EmitType(IList<DynamicProperty> properties, bool createParam
414414
ilgeneratorToString.Emit(OpCodes.Callvirt, StringBuilderAppendString);
415415
ilgeneratorToString.Emit(OpCodes.Pop);
416416
ilgeneratorToString.Emit(OpCodes.Ldloc_0);
417-
ilgeneratorToString.Emit(OpCodes.Callvirt, PredefinedMethodsHelper.ObjectToString);
417+
ilgeneratorToString.Emit(OpCodes.Callvirt, PredefinedMethodsHelper.ObjectInstanceToString);
418418
ilgeneratorToString.Emit(OpCodes.Ret);
419419

420420
EmitEqualityOperators(typeBuilder, equals);
Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,82 @@
11
using System.Collections.Generic;
2-
using System.Linq.Dynamic.Core.Validation;
32
using System.Reflection;
43

54
namespace System.Linq.Dynamic.Core.Parser;
65

7-
internal static class PredefinedMethodsHelper
6+
internal class PredefinedMethodsHelper
87
{
9-
internal static readonly MethodInfo ObjectToString = typeof(object).GetMethod(nameof(ToString), BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null)!;
10-
internal static readonly MethodInfo ObjectInstanceEquals = typeof(object).GetMethod(nameof(Equals), BindingFlags.Instance | BindingFlags.Public, null, [typeof(object)], null)!;
8+
private static readonly BindingFlags _bindingFlags = BindingFlags.Public | BindingFlags.Instance;
9+
10+
internal static readonly MethodInfo ObjectInstanceToString = typeof(object).GetMethod(nameof(ToString), _bindingFlags, null, Type.EmptyTypes, null)!;
11+
internal static readonly MethodInfo ObjectInstanceEquals = typeof(object).GetMethod(nameof(Equals), _bindingFlags, null, [typeof(object)], null)!;
1112
internal static readonly MethodInfo ObjectStaticEquals = typeof(object).GetMethod(nameof(Equals), BindingFlags.Static | BindingFlags.Public, null, [typeof(object), typeof(object)], null)!;
1213
internal static readonly MethodInfo ObjectStaticReferenceEquals = typeof(object).GetMethod(nameof(ReferenceEquals), BindingFlags.Static | BindingFlags.Public, null, [typeof(object), typeof(object)], null)!;
1314

15+
private readonly Dictionary<Type, HashSet<MethodInfo>> _supported = new()
16+
{
17+
{ typeof(bool), new HashSet<MethodInfo>() },
18+
{ typeof(char), new HashSet<MethodInfo>() },
19+
{ typeof(string), new HashSet<MethodInfo>() },
20+
{ typeof(sbyte), new HashSet<MethodInfo>() },
21+
{ typeof(byte), new HashSet<MethodInfo>() },
22+
{ typeof(short), new HashSet<MethodInfo>() },
23+
{ typeof(ushort), new HashSet<MethodInfo>() },
24+
{ typeof(int), new HashSet<MethodInfo>() },
25+
{ typeof(uint), new HashSet<MethodInfo>() },
26+
{ typeof(long), new HashSet<MethodInfo>() },
27+
{ typeof(ulong), new HashSet<MethodInfo>() },
28+
{ typeof(float), new HashSet<MethodInfo>() },
29+
{ typeof(double), new HashSet<MethodInfo>() },
30+
{ typeof(decimal), new HashSet<MethodInfo>() },
31+
// { typeof(DateTime), new HashSet<MethodInfo>() },
32+
// { typeof(DateTimeOffset), new HashSet<MethodInfo>() },
33+
// { typeof(TimeSpan), new HashSet<MethodInfo>() },
34+
// { typeof(Guid), new HashSet<MethodInfo>() },
35+
// { typeof(Uri), new HashSet<MethodInfo>() },
36+
// { typeof(Enum), new HashSet<MethodInfo>() },
37+
#if NET6_0_OR_GREATER
38+
// { typeof(DateOnly), new HashSet<MethodInfo>() },
39+
// { typeof(TimeOnly), new HashSet<MethodInfo>() },
40+
#endif
41+
};
42+
43+
public PredefinedMethodsHelper(ParsingConfig config)
44+
{
45+
foreach (var kvp in _supported)
46+
{
47+
Add(kvp.Key.GetMethod(nameof(Equals), _bindingFlags, null, [kvp.Key], null));
48+
Add(kvp.Key.GetMethod(nameof(Equals), _bindingFlags, null, [typeof(object)], null));
49+
50+
Add(kvp.Key.GetMethod(nameof(ToString), _bindingFlags, null, Type.EmptyTypes, null));
51+
Add(kvp.Key.GetMethod(nameof(ToString), _bindingFlags, null, [typeof(string)], null));
52+
Add(kvp.Key.GetMethod(nameof(ToString), _bindingFlags, null, [typeof(IFormatProvider)], null));
53+
Add(kvp.Key.GetMethod(nameof(ToString), _bindingFlags, null, [typeof(string), typeof(IFormatProvider)], null));
54+
}
1455

15-
private static readonly HashSet<MemberInfo> ObjectToStringAndObjectEquals =
16-
[
17-
ObjectToString,
18-
ObjectInstanceEquals,
19-
ObjectStaticEquals,
20-
ObjectStaticReferenceEquals
21-
];
56+
if (config.AllowEqualsAndToStringMethodsOnObject)
57+
{
58+
_supported[typeof(object)] = [ObjectInstanceToString, ObjectInstanceEquals, ObjectStaticEquals, ObjectStaticReferenceEquals];
59+
}
60+
}
2261

23-
public static bool IsPredefinedMethod(ParsingConfig config, MemberInfo member)
62+
public bool IsPredefinedMethod(Type type, MemberInfo member)
2463
{
25-
Check.NotNull(config);
64+
Check.NotNull(type);
2665
Check.NotNull(member);
2766

28-
return config.AllowEqualsAndToStringMethodsOnObject && ObjectToStringAndObjectEquals.Contains(member);
67+
if (!_supported.TryGetValue(type, out var supported) || supported.Count == 0)
68+
{
69+
return false;
70+
}
71+
72+
return supported.Contains(member);
73+
}
74+
75+
private void Add(Type type, MethodInfo? method)
76+
{
77+
if (method != null)
78+
{
79+
_supported[type].Add(method);
80+
}
2981
}
3082
}

0 commit comments

Comments
 (0)