-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Internal classes with nullable references #5809
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughThe changes introduce nullable reference type annotations across a wide range of internal files, updating fields, parameters, properties, and method signatures to reflect possible null values. Several internal data structures and helper methods are refactored for improved null safety and explicit handling of nulls. Some APIs are updated to return collections or values that may be null, and dictionary-like structures are simplified. The changes do not alter core logic or control flow but focus on type safety and consistency. Changes
Sequence Diagram(s)sequenceDiagram
participant Caller
participant ValidatedConfigurationElement
participant AttributeCollection
Caller->>ValidatedConfigurationElement: Access Values collection
ValidatedConfigurationElement->>AttributeCollection: Return key-value pairs collection (nullable)
Caller->>ValidatedConfigurationElement: Call GetOptionalValue(key, default)
ValidatedConfigurationElement->>AttributeCollection: Check for key, handle null collection
AttributeCollection-->>ValidatedConfigurationElement: Return value or null
ValidatedConfigurationElement-->>Caller: Return value or default
sequenceDiagram
participant InternalClass
participant NullableField
participant Consumer
InternalClass->>NullableField: Set or get value (may be null)
Consumer->>InternalClass: Use value
alt Value is null
InternalClass-->>Consumer: Return null or empty string as appropriate
else Value is not null
InternalClass-->>Consumer: Return actual value
end
Poem
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Caution
Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 6
🔭 Outside diff range comments (4)
src/NLog/Internal/ConfigurationManager.cs (1)
51-53:⚠️ Potential issueHandle potential null return
ConfigurationManager.ConnectionStrings[name]can return null, conflicting with the non-nullable return type. Either update the return signature toConnectionStringSettings?or add a null check with a descriptive exception.src/NLog/Internal/CallSiteInformation.cs (2)
108-112: 🛠️ Refactor suggestionParameter nullability mismatch & redundant null-check
stackTraceis declared as a non-nullable parameter, yet the body immediately guards against it beingnull.
Either the method intends to acceptnull, or the check is dead code:-public void SetStackTrace(StackTrace stackTrace, int? userStackFrame = null, Type? loggerType = null) +public void SetStackTrace(StackTrace? stackTrace, int? userStackFrame = null, Type? loggerType = null)Adjust the caller sites accordingly or drop the
stackTrace != nullcheck.
Having the signature and implementation aligned will avoid confusing warnings and needless branching.
113-118:⚠️ Potential issuePossible NullReference when
GetFrames()returns null
StackTrace.GetFrames()may legitimately returnnull.
If that happens,FindCallingMethodOnStackTracereceives anullarray and later dereferences.Length, leading to an exception.-var stackFrames = stackTrace.GetFrames(); +var stackFrames = stackTrace?.GetFrames() ?? Array.Empty<StackFrame>();Applying this guard keeps the downstream logic intact and eliminates the crash scenario.
src/NLog/Internal/ObjectReflectionCache.cs (1)
106-114: 🛠️ Refactor suggestion
objectPathshould be nullable-annotated if you expectnull
objectPathis declared non-nullable but the very first statement checksif (objectPath is null).
Either drop the test or make the intent explicit:-public bool TryGetObjectProperty(object value, string[] objectPath, out object? foundValue) +public bool TryGetObjectProperty(object value, string[]? objectPath, out object? foundValue)Misaligned annotations defeat the purpose of nullable-reference-type adoption and may hide real defects.
🧹 Nitpick comments (12)
src/NLog/Internal/DynamicallyAccessedMemberTypes.cs (4)
203-203: MarkScopeas nullable
Changingpublic string Scope { get; set; }topublic string? Scope { get; set; }correctly reflects that this property is optional. Consider updating its XML<summary>to note that it may be null.
214-214: MarkTargetas nullable
Updatingpublic string Target { get; set; }topublic string? Target { get; set; }aligns with nullable reference guidelines. Also update its documentation to indicate it can be null when not set.
226-226: MarkMessageIdas nullable
The change fromstringtostring?forMessageIdis appropriate given its optional nature. Please adjust the XML<summary>to mention its nullability.
231-231: MarkJustificationas nullable
AnnotatingJustificationasstring?correctly signals it may be omitted. Consider adding a note to the XML docs that it can be null.src/NLog/Internal/SortHelpers.cs (2)
272-280: Avoid heap-allocating an emptyDictionaryfor the empty enumerator case
GetEnumerator()currently does:return new Enumerator(new Dictionary<TKey, TValue>());That allocates both a dictionary and its enumerator every time an empty instance is enumerated.
You can shave the allocation completely:- else - return new Enumerator(new Dictionary<TKey, TValue>()); + else + return default; // struct enumerator with default(state==empty)You already handle a default-constructed enumerator correctly (
_multiBuckets == null&_singleBucketFirstRead == false).
A small but free performance win.
217-224: Enumerator re-wraps an already correct KeyValuePair – redundant copyInside
Currentfor the multi-bucket path you create a newKeyValuePairfrom the existing one:return new KeyValuePair<TKey, TValue>(_multiBuckets.Current.Key, _multiBuckets.Current.Value);
_multiBuckets.Currentis already the desiredKeyValuePair; the extra copy is unnecessary:- return new KeyValuePair<TKey, TValue>(_multiBuckets.Current.Key, _multiBuckets.Current.Value); + return _multiBuckets.Current;src/NLog/Internal/ISupportsInitialize.cs (1)
38-38: Standardize using directive placement
Movingusing NLog.Config;inside the namespace matches the pattern adopted in other nullable-enabled files. Ensure this style is applied uniformly or consider consolidatingusingdirectives outside namespaces for consistency.src/NLog/Internal/ReusableAsyncLogEventList.cs (1)
38-39: Using directives inside namespace
Relocatingusing System.Collections.Generic;andusing NLog.Common;into theNLog.Internalnamespace follows the pattern in other internal files. Verify that this style is consistently applied across the codebase.src/NLog/Internal/SingleItemOptimizedHashSet.cs (1)
173-194: Duplicate null-checks sprinkled across methods
ContainsandRemoveeach replicate the logic
Count == 1 && _singleItem is not null && Comparer.Equals(_singleItem, item).Consider extracting this into a small helper (
MatchesSingleItem(item)) to keep the code DRY and reduce the chance of future divergence.src/NLog/Internal/CallSiteInformation.cs (2)
171-187: Minor: redundant null-coalescing & micro-optimisationAfter assigning
callerClassName = CallerClassName ?? string.Empty;the variable is nevernull.
Consequently, the laterSubstringbranch can returncallerClassNamedirectly without theelse, and theIsNullOrEmptycheck can be replaced byLength != 0for a tiny perf gain.
Purely optional, but it tightens the intent.
199-204: Redundant null-coalescing in method name retrievalHere you already validated
CallerMethodNameis non-empty; the extra?? string.Emptyis impossible to reach.-if (!string.IsNullOrEmpty(CallerMethodName)) - return CallerMethodName ?? string.Empty; +if (!string.IsNullOrEmpty(CallerMethodName)) + return CallerMethodName; // value cannot be null heresrc/NLog/Internal/ObjectReflectionCache.cs (1)
701-708: Null-safe conversion when reflecting over generic KeyValuePair
keyString.ToString()again assumes non-null; useConvert.ToString(keyString, CultureInfo.InvariantCulture)or the null-conditional above to avoid surprises.
🛑 Comments failed to post (6)
src/NLog/Internal/SortHelpers.cs (2)
112-118:
⚠️ Potential issue
default(KeyValuePair<…>)produces an invalid “phantom” bucketWhen
inputs.Count == 0you construct the return value like this:return new ReadOnlySingleBucketGroupBy<TKey, IList<TValue>>(default(KeyValuePair<TKey, IList<TValue>>), keyComparer);
default(KeyValuePair<TKey, IList<TValue>>)is notnull; the nullable wrapper therefore gets a value withHasValue == truewhose.Keyisdefault(TKey)(nullfor reference-type keys ).
Iteration over the result will thus yield a single element whose key violates theTKey : notnullcontract and will surprise callers that expect an empty collection.- return new ReadOnlySingleBucketGroupBy<TKey, IList<TValue>>(default(KeyValuePair<TKey, IList<TValue>>), keyComparer); + return new ReadOnlySingleBucketGroupBy<TKey, IList<TValue>>(singleBucket: null, keyComparer);(You could also expose an explicit
Emptysingleton on the struct.)
173-181:
⚠️ Potential issueStruct lost IReadOnlyDictionary semantics but the rest of the codebase still relies on them
ReadOnlySingleBucketGroupBynow implements onlyIEnumerable<KeyValuePair<…>>.
However, external code (seeSortHelpersTests.csin this PR and many callers in the repo) still uses:
Keys,ValuesContainsKey,TryGetValue- indexer
[]CopyTo,Count(property), …Because these members are no longer provided (and no extension methods cover them) the solution will not compile.
Two options:
Re-add
IReadOnlyDictionary<TKey,TValue>(preferred – minimal churn for callers)struct ReadOnlySingleBucketGroupBy<TKey,TValue> : IReadOnlyDictionary<TKey,TValue>, IEnumerable<KeyValuePair<TKey,TValue>> where TKey : notnulland implement the missing members using the existing single/multi-bucket backing fields.
If the simplified surface is intentional, update all call-sites and unit tests in this PR accordingly (large scope).
Failing to address this will break the build.
src/NLog/Internal/SingleItemOptimizedHashSet.cs (1)
96-97: 🛠️ Refactor suggestion
Countmisreports whendefault(T)is a legitimate elementUsing
EqualityComparer<T?>.Default.Equals(_singleItem, default(T))treats the default value ofT(e.g.,0,false, empty struct) as absence of an item.
Consequences:
Countreturns 0 after inserting0into aSingleItemOptimizedHashSet<int>.Contains,Remove, enumeration, etc., become inconsistent.A safer pattern is to track presence explicitly (e.g., introduce a private
bool _hasSingleItem) instead of over-loading the default value as a sentinel:-private readonly T? _singleItem; +private readonly T? _singleItem; +private readonly bool _hasSingleItem; ... -public int Count => _hashset?.Count ?? (_hasSingleItem ? 1 : 0);That eliminates ambiguity without affecting the hash-set optimisation.
Committable suggestion skipped: line range outside the PR's diff.
src/NLog/Internal/ReflectionHelpers.cs (1)
68-69:
⚠️ Potential issue
LateBoundMethodshould allownullfor static invocationsThe XML docs explicitly say
targetmay benullfor static methods, yet the delegate signature isobject target(non-nullable under NRT).
Callers will now receive CS8600/CS8625 warnings every time they legitimately passnull.-public delegate object? LateBoundMethod(object target, object[] arguments); +public delegate object? LateBoundMethod(object? target, object[] arguments);This preserves compile-time null-safety while honouring the documented contract.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.public delegate object? LateBoundMethod(object? target, object[] arguments);src/NLog/Internal/ObjectGraphScanner.cs (1)
71-75:
⚠️ Potential issuePossible
NullReferenceExceptionwhenrootObjectscontainsnull
FindReachableObjectsaccessesrootObject.GetType()without a null-check, but later methods now handlenullsafely.
Either filter nulls here or adjust the loop:-foreach (var rootObject in rootObjects) +foreach (var rootObject in rootObjects.Where(o => o is not null))or inside the loop:
if (rootObject is null) continue;Prevents an exception path that unit tests might not cover.
src/NLog/Internal/ObjectReflectionCache.cs (1)
665-668:
⚠️ Potential issue
ToString()on potentially-null key
item.Key(orkeyString) can benull. Calling.ToString()will crash.-yield return new KeyValuePair<string, object?>(item.Key.ToString(), item.Value); +yield return new KeyValuePair<string, object?>(item.Key?.ToString() ?? string.Empty, item.Value);Same applies to the generic overload further down (lines 731-735 & 739-742).
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.{ foreach (var item in new DictionaryEntryEnumerable(dictionary)) yield return new KeyValuePair<string, object?>(item.Key?.ToString() ?? string.Empty, item.Value); }
1a7b3f1 to
f30bb0f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (3)
src/NLog.Targets.ConcurrentFile/Internal/SortHelpers.cs (3)
83-85: Minor: avoid boxing anullintoNullable<>to save an allocationReturning
new ReadOnlySingleBucketGroupBy<TKey, IList<TValue>>(singleBucket: null, …)forces the compiler to allocate a boxedNullable<KeyValuePair<…>>representingnull. A default-constructedReadOnlySingleBucketGroupByalready represents “no buckets”:-return new ReadOnlySingleBucketGroupBy<TKey, IList<TValue>>(singleBucket: null, keyComparer); +return default; // zero-alloc shortcut – struct fields default to nullThis is a micro-optimisation, but bucket-sort helpers may sit on hot paths.
241-249: Avoid allocating an emptyDictionaryeach timeGetEnumerator()is called on an empty group
new Dictionary<TKey, TValue>()creates both a managed object and an internal array simply to provide an enumerator that immediately returnsfalse. A lightweight alternative keeps allocations at zero:-else - return new Enumerator(new Dictionary<TKey, TValue>()); +else + return default; // Enumerator’s default struct value → MoveNext() == falseYou can keep behaviour identical by adding a
defaultconstructor path inEnumeratorthat yieldsfalseonMoveNext().
142-152: Consider exposingIReadOnlyDictionary<TKey,TValue>for discoverabilityAfter the refactor the struct implements only
IEnumerable<KeyValuePair<…>>, yet it advertises aCountproperty and internally represents bucket mappings. ImplementingIReadOnlyDictionary<TKey,TValue>(which is non-mutating) would:
- Preserve the “dictionary-like” intent of the previous type.
- Allow easy key look-ups (
ContainsKey,TryGetValue) without re-enumeration.- Require minimal additional code because most members already exist internally.
If keeping the surface area minimal is intentional, feel free to ignore, but calling this out now avoids future “missing API” churn.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (78)
src/NLog.Targets.ConcurrentFile/Internal/SortHelpers.cs(6 hunks)src/NLog/Config/LoggingConfigurationParser.cs(8 hunks)src/NLog/Internal/AppEnvironmentWrapper.cs(5 hunks)src/NLog/Internal/AppendBuilderCreator.cs(1 hunks)src/NLog/Internal/ArrayHelper.cs(1 hunks)src/NLog/Internal/AssemblyHelpers.cs(1 hunks)src/NLog/Internal/AssemblyMetadataAttribute.cs(1 hunks)src/NLog/Internal/AsyncOperationCounter.cs(5 hunks)src/NLog/Internal/CallSiteInformation.cs(10 hunks)src/NLog/Internal/CollectionExtensions.cs(2 hunks)src/NLog/Internal/ConfigVariablesDictionary.cs(2 hunks)src/NLog/Internal/ConfigurationManager.cs(1 hunks)src/NLog/Internal/DictionaryEntryEnumerable.cs(4 hunks)src/NLog/Internal/DynamicallyAccessedMemberTypes.cs(4 hunks)src/NLog/Internal/EnvironmentHelper.cs(2 hunks)src/NLog/Internal/ExceptionHelper.cs(2 hunks)src/NLog/Internal/ExceptionMessageFormatProvider.cs(2 hunks)src/NLog/Internal/FileInfoHelper.cs(3 hunks)src/NLog/Internal/FormatHelper.cs(3 hunks)src/NLog/Internal/Guard.cs(1 hunks)src/NLog/Internal/IAppEnvironment.cs(1 hunks)src/NLog/Internal/IConfigurationManager.cs(1 hunks)src/NLog/Internal/IFileSystem.cs(1 hunks)src/NLog/Internal/ILogMessageFormatter.cs(1 hunks)src/NLog/Internal/IRawValue.cs(1 hunks)src/NLog/Internal/IRenderable.cs(1 hunks)src/NLog/Internal/IStringValueRenderer.cs(1 hunks)src/NLog/Internal/ISupportsInitialize.cs(1 hunks)src/NLog/Internal/ITargetWithFilterChain.cs(1 hunks)src/NLog/Internal/LogMessageStringFormatter.cs(1 hunks)src/NLog/Internal/LogMessageTemplateFormatter.cs(9 hunks)src/NLog/Internal/MruCache.cs(2 hunks)src/NLog/Internal/MultiFileWatcher.cs(3 hunks)src/NLog/Internal/NativeMethods.cs(1 hunks)src/NLog/Internal/ObjectGraphScanner.cs(4 hunks)src/NLog/Internal/ObjectHandleSerializer.cs(4 hunks)src/NLog/Internal/ObjectPropertyPath.cs(1 hunks)src/NLog/Internal/ObjectReflectionCache.cs(23 hunks)src/NLog/Internal/OverloadResolutionPriorityAttribute.cs(1 hunks)src/NLog/Internal/PathHelpers.cs(2 hunks)src/NLog/Internal/PlatformDetector.cs(1 hunks)src/NLog/Internal/PropertyHelper.cs(20 hunks)src/NLog/Internal/ReflectionHelpers.cs(3 hunks)src/NLog/Internal/ReusableAsyncLogEventList.cs(1 hunks)src/NLog/Internal/ReusableBufferCreator.cs(1 hunks)src/NLog/Internal/ReusableBuilderCreator.cs(1 hunks)src/NLog/Internal/ReusableObjectCreator.cs(1 hunks)src/NLog/Internal/ReusableStreamCreator.cs(2 hunks)src/NLog/Internal/RuntimeOS.cs(1 hunks)src/NLog/Internal/SetupBuilder.cs(1 hunks)src/NLog/Internal/SetupConfigurationLoggingRuleBuilder.cs(2 hunks)src/NLog/Internal/SetupConfigurationTargetBuilder.cs(2 hunks)src/NLog/Internal/SetupExtensionsBuilder.cs(1 hunks)src/NLog/Internal/SetupInternalLoggerBuilder.cs(1 hunks)src/NLog/Internal/SetupLoadConfigurationBuilder.cs(2 hunks)src/NLog/Internal/SetupLogFactoryBuilder.cs(1 hunks)src/NLog/Internal/SetupSerializationBuilder.cs(1 hunks)src/NLog/Internal/SimpleStringReader.cs(1 hunks)src/NLog/Internal/SingleCallContinuation.cs(2 hunks)src/NLog/Internal/SingleItemOptimizedHashSet.cs(9 hunks)src/NLog/Internal/SortHelpers.cs(8 hunks)src/NLog/Internal/StackTraceUsageUtils.cs(10 hunks)src/NLog/Internal/StringBuilderExt.cs(2 hunks)src/NLog/Internal/StringBuilderPool.cs(4 hunks)src/NLog/Internal/StringHelpers.cs(3 hunks)src/NLog/Internal/StringSplitter.cs(1 hunks)src/NLog/Internal/TargetWithFilterChain.cs(11 hunks)src/NLog/Internal/ThreadSafeDictionary.cs(2 hunks)src/NLog/Internal/TimeoutContinuation.cs(2 hunks)src/NLog/Internal/UrlHelper.cs(2 hunks)src/NLog/Internal/XmlHelper.cs(7 hunks)src/NLog/Internal/XmlParser.cs(8 hunks)src/NLog/LayoutRenderers/CallSiteLayoutRenderer.cs(3 hunks)src/NLog/Layouts/Typed/Layout.cs(1 hunks)src/NLog/LoggerImpl.cs(1 hunks)src/NLog/ScopeContext.cs(1 hunks)tests/NLog.UnitTests/Internal/SortHelpersTests.cs(4 hunks)tests/NLog.UnitTests/Internal/XmlParserTests.cs(5 hunks)
✅ Files skipped from review due to trivial changes (8)
- src/NLog/Internal/ArrayHelper.cs
- src/NLog/Internal/PlatformDetector.cs
- src/NLog/Internal/SetupBuilder.cs
- src/NLog/Internal/SimpleStringReader.cs
- src/NLog/Internal/SetupSerializationBuilder.cs
- src/NLog/Internal/LogMessageStringFormatter.cs
- src/NLog/Internal/SetupExtensionsBuilder.cs
- src/NLog/Internal/ConfigurationManager.cs
🚧 Files skipped from review as they are similar to previous changes (69)
- src/NLog/Internal/SetupInternalLoggerBuilder.cs
- src/NLog/Internal/ReusableBufferCreator.cs
- src/NLog/Internal/NativeMethods.cs
- src/NLog/Internal/AssemblyHelpers.cs
- src/NLog/Internal/AppendBuilderCreator.cs
- src/NLog/Internal/IRenderable.cs
- src/NLog/Internal/Guard.cs
- src/NLog/Internal/ITargetWithFilterChain.cs
- src/NLog/Internal/AssemblyMetadataAttribute.cs
- src/NLog/Internal/RuntimeOS.cs
- src/NLog/Internal/UrlHelper.cs
- src/NLog/Internal/IConfigurationManager.cs
- src/NLog/Internal/ILogMessageFormatter.cs
- src/NLog/LoggerImpl.cs
- src/NLog/Internal/ISupportsInitialize.cs
- src/NLog/Internal/IFileSystem.cs
- src/NLog/Internal/IRawValue.cs
- src/NLog/Internal/OverloadResolutionPriorityAttribute.cs
- src/NLog/Internal/TimeoutContinuation.cs
- src/NLog/Internal/IStringValueRenderer.cs
- src/NLog/Internal/PathHelpers.cs
- src/NLog/Internal/ExceptionMessageFormatProvider.cs
- src/NLog/Internal/SetupLogFactoryBuilder.cs
- src/NLog/Internal/StringSplitter.cs
- src/NLog/Internal/CollectionExtensions.cs
- src/NLog/Internal/IAppEnvironment.cs
- src/NLog/Internal/EnvironmentHelper.cs
- src/NLog/LayoutRenderers/CallSiteLayoutRenderer.cs
- src/NLog/Internal/ReusableAsyncLogEventList.cs
- src/NLog/Internal/SingleCallContinuation.cs
- src/NLog/Internal/SetupLoadConfigurationBuilder.cs
- src/NLog/Internal/ReusableBuilderCreator.cs
- src/NLog/Internal/ReusableObjectCreator.cs
- src/NLog/Layouts/Typed/Layout.cs
- src/NLog/Internal/StringHelpers.cs
- src/NLog/Internal/ExceptionHelper.cs
- src/NLog/Internal/ThreadSafeDictionary.cs
- src/NLog/Internal/MruCache.cs
- tests/NLog.UnitTests/Internal/SortHelpersTests.cs
- src/NLog/Internal/SetupConfigurationLoggingRuleBuilder.cs
- src/NLog/Internal/StringBuilderExt.cs
- tests/NLog.UnitTests/Internal/XmlParserTests.cs
- src/NLog/Internal/ReusableStreamCreator.cs
- src/NLog/Internal/ObjectHandleSerializer.cs
- src/NLog/Internal/MultiFileWatcher.cs
- src/NLog/ScopeContext.cs
- src/NLog/Internal/ConfigVariablesDictionary.cs
- src/NLog/Internal/SetupConfigurationTargetBuilder.cs
- src/NLog/Internal/FormatHelper.cs
- src/NLog/Internal/ObjectPropertyPath.cs
- src/NLog/Internal/StringBuilderPool.cs
- src/NLog/Internal/AsyncOperationCounter.cs
- src/NLog/Internal/SingleItemOptimizedHashSet.cs
- src/NLog/Internal/FileInfoHelper.cs
- src/NLog/Internal/DictionaryEntryEnumerable.cs
- src/NLog/Internal/ObjectGraphScanner.cs
- src/NLog/Internal/DynamicallyAccessedMemberTypes.cs
- src/NLog/Internal/XmlHelper.cs
- src/NLog/Internal/ReflectionHelpers.cs
- src/NLog/Internal/AppEnvironmentWrapper.cs
- src/NLog/Internal/StackTraceUsageUtils.cs
- src/NLog/Internal/SortHelpers.cs
- src/NLog/Config/LoggingConfigurationParser.cs
- src/NLog/Internal/TargetWithFilterChain.cs
- src/NLog/Internal/LogMessageTemplateFormatter.cs
- src/NLog/Internal/XmlParser.cs
- src/NLog/Internal/PropertyHelper.cs
- src/NLog/Internal/CallSiteInformation.cs
- src/NLog/Internal/ObjectReflectionCache.cs
|




Initial step for #4036