Skip to content

Commit 84a8349

Browse files
authored
Avoid boxing ITuple when used for BeginScope (#814)
1 parent b31c054 commit 84a8349

File tree

1 file changed

+90
-90
lines changed

1 file changed

+90
-90
lines changed

src/NLog.Extensions.Logging/Logging/NLogBeginScopeParser.cs

Lines changed: 90 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ public IDisposable ParseBeginScope<T>(T state)
4646
return ScopeContext.PushNestedStateProperties(scopeProperties, scopeProperties);
4747
}
4848
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER || NET471_OR_GREATER
49-
else if (state is System.Runtime.CompilerServices.ITuple tuple && tuple.Length == 2 && tuple[0] is string)
49+
else if (state is System.Runtime.CompilerServices.ITuple && ((System.Runtime.CompilerServices.ITuple)state).Length == 2 && ((System.Runtime.CompilerServices.ITuple)state)[0] is string)
5050
{
51-
return ScopeContext.PushProperty(tuple[0]?.ToString() ?? string.Empty, tuple[1]);
51+
return ScopeContext.PushProperty(((System.Runtime.CompilerServices.ITuple)state)[0]?.ToString() ?? string.Empty, ((System.Runtime.CompilerServices.ITuple)state)[1]);
5252
}
5353
#endif
5454

@@ -238,7 +238,7 @@ private static bool TryLookupExtractor<TState>(ExtractorDictionary stateExtracto
238238
out Func<object, KeyValuePair<string, object?>>? keyValueExtractor)
239239
{
240240
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER || NET471_OR_GREATER
241-
if (propertyValue is System.Runtime.CompilerServices.ITuple tuple && tuple.Length == 2 && tuple[0] is string)
241+
if (propertyValue is System.Runtime.CompilerServices.ITuple && ((System.Runtime.CompilerServices.ITuple)propertyValue).Length == 2 && ((System.Runtime.CompilerServices.ITuple)propertyValue)[0] is string)
242242
{
243243
keyValueExtractor = static (obj) => new KeyValuePair<string, object?>(
244244
((System.Runtime.CompilerServices.ITuple)obj)[0]?.ToString() ?? string.Empty,
@@ -272,38 +272,20 @@ private static bool TryBuildExtractor(Type propertyType, out Func<object, KeyVal
272272
{
273273
keyValueExtractor = null;
274274

275-
var itemType = propertyType.GetTypeInfo();
276-
if (!itemType.IsGenericType)
275+
if (!propertyType.IsGenericType)
277276
return false;
278277

279-
if (itemType.GetGenericTypeDefinition() == typeof(KeyValuePair<,>))
278+
if (propertyType.GetGenericTypeDefinition() == typeof(KeyValuePair<,>))
280279
{
281-
#if NETSTANDARD || NETFRAMEWORK
282-
var keyPropertyInfo = typeof(KeyValuePair<,>).MakeGenericType(itemType.GenericTypeArguments).GetTypeInfo().GetDeclaredProperty(nameof(KeyValuePair<string, object>.Key));
283-
var valuePropertyInfo = typeof(KeyValuePair<,>).MakeGenericType(itemType.GenericTypeArguments).GetTypeInfo().GetDeclaredProperty(nameof(KeyValuePair<string, object>.Value));
284-
if (valuePropertyInfo is null || keyPropertyInfo is null)
285-
{
286-
return false;
287-
}
288-
289-
var keyValuePairObjParam = Expression.Parameter(typeof(object), "KeyValuePair");
290-
var keyValuePairTypeParam = Expression.Convert(keyValuePairObjParam, propertyType);
291-
var propertyKeyAccess = Expression.Property(keyValuePairTypeParam, keyPropertyInfo);
292-
var propertyValueAccess = Expression.Property(keyValuePairTypeParam, valuePropertyInfo);
293-
return BuildKeyValueExtractor(keyValuePairObjParam, propertyKeyAccess, propertyValueAccess, out keyValueExtractor);
294-
#else
295-
if (itemType.GenericTypeArguments[0] == typeof(string))
296-
{
297-
return BuildKeyValueExtractor(propertyType, out keyValueExtractor);
298-
}
299-
#endif
280+
return BuildKeyValueExtractor(propertyType, out keyValueExtractor);
300281
}
301282

302-
#if NETSTANDARD || NETFRAMEWORK
303-
if (itemType.GetGenericTypeDefinition() == typeof(ValueTuple<,>))
283+
#if !NETSTANDARD2_1_OR_GREATER && !NETCOREAPP3_1_OR_GREATER && !NET471_OR_GREATER
284+
if (propertyType.GetGenericTypeDefinition() == typeof(ValueTuple<,>))
304285
{
305-
var keyPropertyInfo = typeof(ValueTuple<,>).MakeGenericType(itemType.GenericTypeArguments).GetTypeInfo().GetDeclaredField("Item1");
306-
var valuePropertyInfo = typeof(ValueTuple<,>).MakeGenericType(itemType.GenericTypeArguments).GetTypeInfo().GetDeclaredField("Item2");
286+
var itemType = propertyType.GetTypeInfo();
287+
var keyPropertyInfo = itemType.GetDeclaredField("Item1");
288+
var valuePropertyInfo = itemType.GetDeclaredField("Item2");
307289
if (valuePropertyInfo is null || keyPropertyInfo is null)
308290
{
309291
return false;
@@ -316,6 +298,7 @@ private static bool TryBuildExtractor(Type propertyType, out Func<object, KeyVal
316298
return BuildKeyValueExtractor(keyValuePairObjParam, propertyKeyAccess, propertyValueAccess, out keyValueExtractor);
317299
}
318300
#endif
301+
319302
return false;
320303
}
321304

@@ -327,70 +310,14 @@ private static bool TryBuildExtractor(Type propertyType, out Func<object, KeyVal
327310
}
328311

329312
[System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("Trimming - Allow reflection of BeginScope args", "IL2070")]
330-
private static bool BuildKeyValueExtractor(Type propertyType, out Func<object, KeyValuePair<string, object?>>? keyValueExtractor)
313+
#endif
314+
private static bool BuildKeyValueExtractor(Type propertyType, TypeInfo itemType, out Func<object, KeyValuePair<string, object?>>? keyValueExtractor)
331315
{
332-
var itemType = propertyType.GetTypeInfo();
333-
if (itemType.GenericTypeArguments[1] == typeof(object))
334-
{
335-
keyValueExtractor = TypedKeyValueExtractor<string, object>;
336-
return true;
337-
}
338-
if (itemType.GenericTypeArguments[1] == typeof(string))
339-
{
340-
keyValueExtractor = TypedKeyValueExtractor<string, string>;
341-
return true;
342-
}
343-
if (itemType.GenericTypeArguments[1] == typeof(int))
344-
{
345-
keyValueExtractor = TypedKeyValueExtractor<string, int>;
346-
return true;
347-
}
348-
if (itemType.GenericTypeArguments[1] == typeof(long))
349-
{
350-
keyValueExtractor = TypedKeyValueExtractor<string, long>;
351-
return true;
352-
}
353-
if (itemType.GenericTypeArguments[1] == typeof(decimal))
354-
{
355-
keyValueExtractor = TypedKeyValueExtractor<string, decimal>;
356-
return true;
357-
}
358-
if (itemType.GenericTypeArguments[1] == typeof(double))
359-
{
360-
keyValueExtractor = TypedKeyValueExtractor<string, double>;
361-
return true;
362-
}
363-
if (itemType.GenericTypeArguments[1] == typeof(bool))
364-
{
365-
keyValueExtractor = TypedKeyValueExtractor<string, bool>;
366-
return true;
367-
}
368-
if (itemType.GenericTypeArguments[1] == typeof(Guid))
369-
{
370-
keyValueExtractor = TypedKeyValueExtractor<string, Guid>;
371-
return true;
372-
}
373-
if (itemType.GenericTypeArguments[1] == typeof(DateTime))
374-
{
375-
keyValueExtractor = TypedKeyValueExtractor<string, DateTime>;
376-
return true;
377-
}
378-
if (itemType.GenericTypeArguments[1] == typeof(DateTimeOffset))
379-
{
380-
keyValueExtractor = TypedKeyValueExtractor<string, DateTimeOffset>;
381-
return true;
382-
}
383-
if (itemType.GenericTypeArguments[1] == typeof(TimeSpan))
384-
{
385-
keyValueExtractor = TypedKeyValueExtractor<string, TimeSpan>;
386-
return true;
387-
}
388-
389-
var keyPropertyInfo = propertyType.GetTypeInfo().GetDeclaredProperty(nameof(KeyValuePair<string,object>.Key));
390-
var valuePropertyInfo = propertyType.GetTypeInfo().GetDeclaredProperty(nameof(KeyValuePair<string, object>.Value));
316+
var keyPropertyInfo = itemType.GetDeclaredProperty(nameof(KeyValuePair<string, object>.Key));
317+
var valuePropertyInfo = itemType.GetDeclaredProperty(nameof(KeyValuePair<string, object>.Value));
391318
if (valuePropertyInfo is null || keyPropertyInfo is null)
392319
{
393-
keyValueExtractor = default;
320+
keyValueExtractor = null;
394321
return false;
395322
}
396323

@@ -400,7 +327,80 @@ private static bool BuildKeyValueExtractor(Type propertyType, out Func<object, K
400327
var propertyValueAccess = Expression.Property(keyValuePairTypeParam, valuePropertyInfo);
401328
return BuildKeyValueExtractor(keyValuePairObjParam, propertyKeyAccess, propertyValueAccess, out keyValueExtractor);
402329
}
330+
331+
private static bool BuildKeyValueExtractor(Type propertyType, out Func<object, KeyValuePair<string, object?>>? keyValueExtractor)
332+
{
333+
#if NETSTANDARD || NETFRAMEWORK
334+
var itemType = propertyType.GetTypeInfo();
335+
return BuildKeyValueExtractor(propertyType, itemType, out keyValueExtractor);
336+
#else
337+
if (propertyType.GenericTypeArguments[0] == typeof(string))
338+
{
339+
if (propertyType.GenericTypeArguments[1] == typeof(object))
340+
{
341+
keyValueExtractor = TypedKeyValueExtractor<string, object>;
342+
return true;
343+
}
344+
if (propertyType.GenericTypeArguments[1] == typeof(string))
345+
{
346+
keyValueExtractor = TypedKeyValueExtractor<string, string>;
347+
return true;
348+
}
349+
if (propertyType.GenericTypeArguments[1] == typeof(int))
350+
{
351+
keyValueExtractor = TypedKeyValueExtractor<string, int>;
352+
return true;
353+
}
354+
if (propertyType.GenericTypeArguments[1] == typeof(long))
355+
{
356+
keyValueExtractor = TypedKeyValueExtractor<string, long>;
357+
return true;
358+
}
359+
if (propertyType.GenericTypeArguments[1] == typeof(decimal))
360+
{
361+
keyValueExtractor = TypedKeyValueExtractor<string, decimal>;
362+
return true;
363+
}
364+
if (propertyType.GenericTypeArguments[1] == typeof(double))
365+
{
366+
keyValueExtractor = TypedKeyValueExtractor<string, double>;
367+
return true;
368+
}
369+
if (propertyType.GenericTypeArguments[1] == typeof(bool))
370+
{
371+
keyValueExtractor = TypedKeyValueExtractor<string, bool>;
372+
return true;
373+
}
374+
if (propertyType.GenericTypeArguments[1] == typeof(Guid))
375+
{
376+
keyValueExtractor = TypedKeyValueExtractor<string, Guid>;
377+
return true;
378+
}
379+
if (propertyType.GenericTypeArguments[1] == typeof(DateTime))
380+
{
381+
keyValueExtractor = TypedKeyValueExtractor<string, DateTime>;
382+
return true;
383+
}
384+
if (propertyType.GenericTypeArguments[1] == typeof(DateTimeOffset))
385+
{
386+
keyValueExtractor = TypedKeyValueExtractor<string, DateTimeOffset>;
387+
return true;
388+
}
389+
if (propertyType.GenericTypeArguments[1] == typeof(TimeSpan))
390+
{
391+
keyValueExtractor = TypedKeyValueExtractor<string, TimeSpan>;
392+
return true;
393+
}
394+
395+
var itemType = propertyType.GetTypeInfo();
396+
return BuildKeyValueExtractor(propertyType, itemType, out keyValueExtractor);
397+
}
398+
399+
keyValueExtractor = null;
400+
return false;
403401
#endif
402+
}
403+
404404
private static bool BuildKeyValueExtractor(ParameterExpression keyValuePairObjParam, MemberExpression propertyKeyAccess, MemberExpression propertyValueAccess, out Func<object, KeyValuePair<string, object?>> keyValueExtractor)
405405
{
406406
var propertyKeyAccessObj = Expression.Convert(propertyKeyAccess, typeof(object));

0 commit comments

Comments
 (0)