Nullability and modernization updates, part 3 (#126)
* Nullability and modernization updates, part 3
* PR comments and fix remoting NDC test
* Additional PR comment
diff --git a/src/log4net.Tests/Appender/RemotingAppenderTest.cs b/src/log4net.Tests/Appender/RemotingAppenderTest.cs
index 5119874..511b221 100644
--- a/src/log4net.Tests/Appender/RemotingAppenderTest.cs
+++ b/src/log4net.Tests/Appender/RemotingAppenderTest.cs
@@ -22,6 +22,8 @@
using System;
using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
using System.Reflection;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
@@ -47,7 +49,7 @@
[TestFixture]
public class RemotingAppenderTest
{
- private IChannel m_remotingChannel = null;
+ private IChannel? m_remotingChannel;
/// <summary>
/// Test that the Message property is correctly remoted
@@ -55,21 +57,20 @@
[Test]
public void TestRemotedMessage()
{
- // Setup the remoting appender
+ // Set up the remoting appender
ConfigureRootAppender(FixFlags.Partial);
RemoteLoggingSinkImpl.Instance.Reset();
- Logger root;
- root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;
+ Logger root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;
- string testMessage = string.Format("test message [ {0} ]", (new Random()).Next());
+ string testMessage = $"test message [ {(new Random()).Next()} ]";
// Log a message that will be remoted
root.Log(Level.Debug, testMessage, null);
// Wait for the remoted object to be delivered
- Thread.Sleep(2000);
+ WaitFor("Remote instance should have received all remoting events", () => RemoteLoggingSinkImpl.Instance.Events.Length > 0);
LoggingEvent[] events = RemoteLoggingSinkImpl.Instance.Events;
Assert.AreEqual(1, events.Length, "Expect to receive 1 remoted event");
@@ -83,19 +84,18 @@
[Test]
public void TestPartialFix()
{
- // Setup the remoting appender
+ // Set up the remoting appender
ConfigureRootAppender(FixFlags.Partial);
RemoteLoggingSinkImpl.Instance.Reset();
- Logger root;
- root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;
+ Logger root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;
// Log a message that will be remoted
root.Log(Level.Debug, "test message", null);
// Wait for the remoted object to be delivered
- Thread.Sleep(2000);
+ WaitFor("Remote instance should have received all remoting events", () => RemoteLoggingSinkImpl.Instance.Events.Length > 0);
LoggingEvent[] events = RemoteLoggingSinkImpl.Instance.Events;
Assert.AreEqual(1, events.Length, "Expect to receive 1 remoted event");
@@ -109,20 +109,17 @@
[Test]
public void TestFullFix()
{
- // Setup the remoting appender
+ // Set up the remoting appender
ConfigureRootAppender(FixFlags.All);
RemoteLoggingSinkImpl.Instance.Reset();
- Logger root;
- root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;
+ Logger root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;
// Log a message that will be remoted
root.Log(Level.Debug, "test message", null);
// Wait for the remoted object to be delivered
- Thread.Sleep(5000);
-
WaitFor("Remote instance should have received a remoting event", () => RemoteLoggingSinkImpl.Instance.Events.Length > 0);
LoggingEvent[] events = RemoteLoggingSinkImpl.Instance.Events;
Assert.AreEqual(1, events.Length, "Expect to receive 1 remoted event");
@@ -130,7 +127,7 @@
Assert.IsNotNull(events[0].LocationInfo, "Expect LocationInfo to not be null because doing a full fix");
}
- private void WaitFor(
+ private static void WaitFor(
string failMessage,
Func<bool> condition,
int maxWaitMilliseconds = 5000)
@@ -139,7 +136,9 @@
do
{
if (condition())
+ {
return;
+ }
Thread.Sleep(100);
} while ((DateTime.Now - start).TotalMilliseconds < maxWaitMilliseconds);
throw new TimeoutException($"Condition not achieved within {maxWaitMilliseconds}ms: {failMessage}");
@@ -151,15 +150,14 @@
[Test]
public void TestRemotedMessageNdcPushPop()
{
- // Setup the remoting appender
+ // Set up the remoting appender
ConfigureRootAppender(FixFlags.Partial);
RemoteLoggingSinkImpl.Instance.Reset();
- Logger root;
- root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;
+ Logger root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;
- string testMessage = string.Format("test message [ {0} ]", (new Random()).Next());
+ string testMessage = $"test message [ {(new Random()).Next()} ]";
using (NDC.Push("value"))
{
@@ -169,7 +167,7 @@
root.Log(Level.Debug, testMessage, null);
// Wait for the remoted object to be delivered
- Thread.Sleep(2000);
+ WaitFor("Remote instance should have received all remoting events", () => RemoteLoggingSinkImpl.Instance.Events.Length > 0);
LoggingEvent[] events = RemoteLoggingSinkImpl.Instance.Events;
Assert.AreEqual(1, events.Length, "Expect to receive 1 remoted event");
@@ -180,47 +178,43 @@
[Test]
public void TestNestedNdc()
{
- // This test can suffer from timing and ordering issues as the RemotingAppender does dispatch events asynchronously
-
- // Setup the remoting appender
+ // Set up the remoting appender
ConfigureRootAppender(FixFlags.Partial);
RemoteLoggingSinkImpl.Instance.Reset();
- TestService t;
- t = new TestService();
+ var t = new TestService();
t.Test();
- // Wait for the remoted objects to be delivered
- Thread.Sleep(3000);
+ WaitFor("Remote instance should have received all remoting events", () => RemoteLoggingSinkImpl.Instance.Events.Length == 5);
LoggingEvent[] events = RemoteLoggingSinkImpl.Instance.Events;
- Assert.AreEqual(5, events.Length, "Expect to receive 5 remoted event");
- Assert.AreEqual("begin test", events[0].RenderedMessage, "Verify event 1 RenderedMessage");
- Assert.AreEqual("feature", events[1].RenderedMessage, "Verify event 2 RenderedMessage");
- Assert.AreEqual("return", events[2].RenderedMessage, "Verify event 3 RenderedMessage");
- Assert.AreEqual("return", events[3].RenderedMessage, "Verify event 4 RenderedMessage");
- Assert.AreEqual("end test", events[4].RenderedMessage, "Verify event 5 RenderedMessage");
+ // RemotingAppender dispatches events asynchronously, messages could be in any order.
+ LoggingEvent beingTest = events.First(e => e.RenderedMessage == "begin test");
+ Assert.IsNull(beingTest.Properties["NDC"], "Verify 'being test' event Properties");
- Assert.IsNull(events[0].Properties["NDC"], "Verify event 1 Properties");
- Assert.AreEqual("test1", events[1].Properties["NDC"], "Verify event 2 Properties");
- Assert.AreEqual("test1 test2", events[2].Properties["NDC"], "Verify event 3 Properties");
- Assert.AreEqual("test1", events[3].Properties["NDC"], "Verify event 4 Properties");
- Assert.IsNull(events[4].Properties["NDC"], "Verify event 5 Properties");
+ LoggingEvent feature = events.First(e => e.RenderedMessage == "feature");
+ Assert.AreEqual("test1", feature.Properties["NDC"], "Verify 'feature' event Properties");
+
+ LoggingEvent return1 = events.First(e => e.RenderedMessage == "return" && Equals(e.Properties["NDC"], "test1 test2"));
+
+ LoggingEvent return2 = events.First(e => e.RenderedMessage == "return" && Equals(e.Properties["NDC"], "test1"));
+
+ LoggingEvent endTest = events.First(e => e.RenderedMessage == "end test");
+ Assert.IsNull(endTest.Properties["NDC"], "Verify 'end test' event Properties");
}
-
private void RegisterRemotingServerChannel()
{
- if (m_remotingChannel == null)
+ if (m_remotingChannel is null)
{
BinaryClientFormatterSinkProvider clientSinkProvider = new BinaryClientFormatterSinkProvider();
BinaryServerFormatterSinkProvider serverSinkProvider = new BinaryServerFormatterSinkProvider();
serverSinkProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
- Hashtable channelProperties = new Hashtable();
+ var channelProperties = new Hashtable();
channelProperties["port"] = 8085;
m_remotingChannel = new TcpChannel(channelProperties, clientSinkProvider, serverSinkProvider);
@@ -277,7 +271,7 @@
[OneTimeTearDown]
public void UnregisterRemotingServerChannel()
{
- if (m_remotingChannel != null)
+ if (m_remotingChannel is not null)
{
((TcpChannel)m_remotingChannel).StopListening(null);
try
@@ -296,20 +290,21 @@
/// </summary>
private static void ConfigureRootAppender(FixFlags fixFlags)
{
- Logger root;
- root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;
+ Logger root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;
root.Level = Level.Debug;
root.AddAppender(CreateAppender(fixFlags));
- root.Repository.Configured = true;
+ root.Repository!.Configured = true;
}
private static RemotingAppender CreateAppender(FixFlags fixFlags)
{
- RemotingAppender appender = new RemotingAppender();
- appender.Sink = "tcp://localhost:8085/LoggingSink";
- appender.Lossy = false;
- appender.BufferSize = 1;
- appender.Fix = fixFlags;
+ var appender = new RemotingAppender
+ {
+ Sink = "tcp://localhost:8085/LoggingSink",
+ Lossy = false,
+ BufferSize = 1,
+ Fix = fixFlags
+ };
appender.ActivateOptions();
@@ -318,33 +313,25 @@
public class RemoteLoggingSinkImpl : MarshalByRefObject, RemotingAppender.IRemoteLoggingSink
{
- public static readonly RemoteLoggingSinkImpl Instance = new RemoteLoggingSinkImpl();
+ public static readonly RemoteLoggingSinkImpl Instance = new();
- private ArrayList m_events = new ArrayList();
+ private readonly List<LoggingEvent> m_events = new();
- #region Public Instance Constructors
private RemoteLoggingSinkImpl()
{
}
- #endregion Public Instance Constructors
- #region Implementation of IRemoteLoggingSink
/// <summary>
- /// Logs the events to to an internal buffer
+ /// Logs the events to an internal buffer.
/// </summary>
/// <param name="events">The events to log.</param>
/// <remarks>
- /// Logs the events to to an internal buffer. The logged events can
+ /// The logged events can
/// be retrieved via the <see cref="Events"/> property. To clear
/// the buffer call the <see cref="Reset"/> method.
/// </remarks>
- public void LogEvents(LoggingEvent[] events)
- {
- m_events.AddRange(events);
- }
- #endregion Implementation of IRemoteLoggingSink
+ public void LogEvents(LoggingEvent[] events) => m_events.AddRange(events);
- #region Override implementation of MarshalByRefObject
/// <summary>
/// Obtains a lifetime service object to control the lifetime
/// policy for this instance.
@@ -353,21 +340,14 @@
/// <c>null</c> to indicate that this instance should live
/// forever.
/// </returns>
- public override object InitializeLifetimeService()
+ public override object? InitializeLifetimeService()
{
return null;
}
- #endregion Override implementation of MarshalByRefObject
- public void Reset()
- {
- m_events.Clear();
- }
+ public void Reset() => m_events.Clear();
- public LoggingEvent[] Events
- {
- get { return (LoggingEvent[])m_events.ToArray(typeof(LoggingEvent)); }
- }
+ public LoggingEvent[] Events => m_events.ToArray();
}
}
}
@@ -378,14 +358,14 @@
{
public class TestService
{
- private static ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+ private static ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod()!.DeclaringType!);
public void Test()
{
log.Info("begin test");
Thread.Sleep(100);
- Feature f = new Feature();
+ var f = new Feature();
f.Test();
log.Info("end test");
Thread.Sleep(100);
@@ -399,7 +379,7 @@
{
public class Feature
{
- private static ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+ private static ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod()!.DeclaringType!);
public void Test()
{
@@ -408,7 +388,7 @@
log.Info("feature");
Thread.Sleep(100);
- Dal d = new Dal();
+ var d = new Dal();
d.Test();
log.Info("return");
Thread.Sleep(100);
@@ -423,7 +403,7 @@
{
public class Dal
{
- private static ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+ private static ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod()!.DeclaringType!);
public void Test()
{
diff --git a/src/log4net.Tests/Appender/StringAppender.cs b/src/log4net.Tests/Appender/StringAppender.cs
index 83602f8..90e0c6e 100644
--- a/src/log4net.Tests/Appender/StringAppender.cs
+++ b/src/log4net.Tests/Appender/StringAppender.cs
@@ -30,7 +30,7 @@
/// <author>Nicko Cadell</author>
public class StringAppender : AppenderSkeleton
{
- private StringBuilder m_buf = new StringBuilder();
+ private StringBuilder m_buf = new();
/// <summary>
/// Initializes a new instance of the <see cref="StringAppender" /> class.
@@ -68,9 +68,6 @@
/// This appender requires a <see cref="Layout"/> to be set.
/// </summary>
/// <value><c>true</c></value>
- protected override bool RequiresLayout
- {
- get { return true; }
- }
+ protected override bool RequiresLayout => true;
}
}
\ No newline at end of file
diff --git a/src/log4net.Tests/Context/LogicalThreadContextTest.cs b/src/log4net.Tests/Context/LogicalThreadContextTest.cs
index 8d61a39..b4861e0 100644
--- a/src/log4net.Tests/Context/LogicalThreadContextTest.cs
+++ b/src/log4net.Tests/Context/LogicalThreadContextTest.cs
@@ -29,6 +29,8 @@
using NUnit.Framework;
+#nullable enable
+
namespace log4net.Tests.Context
{
/// <summary>
@@ -253,7 +255,7 @@
stringAppender.Reset();
string testValueForCurrentContext = "Outer";
- string[] strings = null;
+ string[]? strings;
using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push(testValueForCurrentContext))
{
log1.Info("TestMessage");
@@ -304,10 +306,12 @@
log.Info("TestMessage");
}
- static async Task<string> SomeWorkStack(string stackName)
+ private static async Task<string> SomeWorkStack(string stackName)
{
- StringAppender stringAppender = new StringAppender();
- stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
+ var stringAppender = new StringAppender
+ {
+ Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}")
+ };
ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
BasicConfigurator.Configure(rep, stringAppender);
diff --git a/src/log4net.Tests/Context/ThreadContextTest.cs b/src/log4net.Tests/Context/ThreadContextTest.cs
index f08a63c..a01ca03 100644
--- a/src/log4net.Tests/Context/ThreadContextTest.cs
+++ b/src/log4net.Tests/Context/ThreadContextTest.cs
@@ -21,6 +21,7 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Threading;
using log4net.Config;
@@ -35,9 +36,6 @@
/// <summary>
/// Used for internal unit testing the <see cref="ThreadContext"/> class.
/// </summary>
- /// <remarks>
- /// Used for internal unit testing the <see cref="ThreadContext"/> class.
- /// </remarks>
[TestFixture]
public class ThreadContextTest
{
@@ -197,36 +195,36 @@
stringAppender.Reset();
}
- private static string TestBackgroundThreadContextPropertyRepository;
-
[Test]
public void TestBackgroundThreadContextProperty()
{
StringAppender stringAppender = new StringAppender();
stringAppender.Layout = new PatternLayout("%property{DateTimeTodayToString}");
- ILoggerRepository rep = LogManager.CreateRepository(TestBackgroundThreadContextPropertyRepository =
- "TestBackgroundThreadContextPropertyRepository" + Guid.NewGuid().ToString());
+ string testBackgroundThreadContextPropertyRepository =
+ "TestBackgroundThreadContextPropertyRepository" + Guid.NewGuid();
+ ILoggerRepository rep = LogManager.CreateRepository(testBackgroundThreadContextPropertyRepository);
BasicConfigurator.Configure(rep, stringAppender);
- Thread thread = new Thread(new ThreadStart(ExecuteBackgroundThread));
- thread.Start();
+ Thread thread = new Thread(ExecuteBackgroundThread);
+ thread.Start(testBackgroundThreadContextPropertyRepository);
Thread.CurrentThread.Join(2000);
}
- private static void ExecuteBackgroundThread()
+ private static void ExecuteBackgroundThread(object context)
{
- ILog log = LogManager.GetLogger(TestBackgroundThreadContextPropertyRepository, "ExecuteBackGroundThread");
- ThreadContext.Properties["DateTimeTodayToString"] = DateTime.Today.ToString();
+ string testBackgroundThreadContextPropertyRepository = (string)context;
+ ILog log = LogManager.GetLogger(testBackgroundThreadContextPropertyRepository, "ExecuteBackGroundThread");
+ ThreadContext.Properties["DateTimeTodayToString"] = DateTime.Today.ToString(CultureInfo.InvariantCulture);
log.Info("TestMessage");
Repository.Hierarchy.Hierarchy hierarchyLoggingRepository =
(Repository.Hierarchy.Hierarchy)log.Logger.Repository;
- StringAppender stringAppender = (StringAppender)hierarchyLoggingRepository.Root.Appenders[0];
+ StringAppender stringAppender = (StringAppender)hierarchyLoggingRepository!.Root.Appenders[0];
- Assert.AreEqual(DateTime.Today.ToString(), stringAppender.GetString());
+ Assert.AreEqual(DateTime.Today.ToString(CultureInfo.InvariantCulture), stringAppender.GetString());
}
[Test]
@@ -237,7 +235,7 @@
var flags = new List<FlagContainer>();
// Act
- for (var i = 0; i < 256; i++)
+ for (var i = 0; i < Math.Max(64, 4 * Environment.ProcessorCount); i++)
{
var t = new Thread(SpinAndCheck);
var flag = new FlagContainer();
@@ -261,7 +259,7 @@
private void SpinAndCheck(object obj)
{
- var container = obj as FlagContainer;
+ var container = (FlagContainer)obj;
var threadid = Thread.CurrentThread.ManagedThreadId;
for (var i = 0; i < 100000; i++)
{
diff --git a/src/log4net.Tests/Core/DefaultRepositorySelectorTest.cs b/src/log4net.Tests/Core/DefaultRepositorySelectorTest.cs
index 024e03d..a052592 100644
--- a/src/log4net.Tests/Core/DefaultRepositorySelectorTest.cs
+++ b/src/log4net.Tests/Core/DefaultRepositorySelectorTest.cs
@@ -21,7 +21,6 @@
using System.Collections;
using System.Collections.Generic;
using log4net.Appender;
-using log4net.Config;
using log4net.Core;
using log4net.ObjectRenderer;
using log4net.Plugin;
@@ -183,7 +182,5 @@
}
}
- internal class MockLoggerRepository2 : MockLoggerRepository
- {
- }
+ internal class MockLoggerRepository2 : MockLoggerRepository;
}
diff --git a/src/log4net.Tests/Hierarchy/LoggerTest.cs b/src/log4net.Tests/Hierarchy/LoggerTest.cs
index b03357b..6dbd233 100644
--- a/src/log4net.Tests/Hierarchy/LoggerTest.cs
+++ b/src/log4net.Tests/Hierarchy/LoggerTest.cs
@@ -71,6 +71,7 @@
{
Assert.IsTrue(enumAppenders.MoveNext());
var aHat = (CountingAppender?)enumAppenders.Current;
+ Assert.IsNotNull(aHat);
Assert.AreEqual(a1, aHat);
}
finally
@@ -101,6 +102,7 @@
Assert.AreEqual(a1, aHat);
aHat = (CountingAppender?)log.GetAppender(a2.Name);
+ Assert.IsNotNull(aHat);
Assert.AreEqual(a2, aHat);
// By name.
@@ -113,6 +115,7 @@
{
Assert.IsTrue(enumAppenders.MoveNext());
aHat = (CountingAppender?)enumAppenders.Current;
+ Assert.IsNotNull(aHat);
Assert.AreSame(a2, aHat);
Assert.IsFalse(enumAppenders.MoveNext());
}
@@ -125,6 +128,7 @@
}
aHat = (CountingAppender?)log.GetAppender(a2.Name);
+ Assert.IsNotNull(aHat);
Assert.AreSame(a2, aHat);
// By appender.
@@ -154,7 +158,7 @@
{
Logger a = (Logger)LogManager.GetLogger("a").Logger;
Logger ab = (Logger)LogManager.GetLogger("a.b").Logger;
- CountingAppender ca = new CountingAppender();
+ var ca = new CountingAppender();
a.AddAppender(ca);
Assert.IsNotNull(a.Repository);
@@ -182,8 +186,8 @@
Logger abc = (Logger)LogManager.GetLogger("a.b.c").Logger;
Logger x = (Logger)LogManager.GetLogger("x").Logger;
- CountingAppender ca1 = new CountingAppender();
- CountingAppender ca2 = new CountingAppender();
+ var ca1 = new CountingAppender();
+ var ca2 = new CountingAppender();
a.AddAppender(ca1);
abc.AddAppender(ca2);
@@ -217,9 +221,9 @@
Logger ab = (Logger)LogManager.GetLogger("a.b").Logger;
Logger abc = (Logger)LogManager.GetLogger("a.b.c").Logger;
- CountingAppender caRoot = new CountingAppender();
- CountingAppender caA = new CountingAppender();
- CountingAppender caABC = new CountingAppender();
+ var caRoot = new CountingAppender();
+ var caA = new CountingAppender();
+ var caABC = new CountingAppender();
root.AddAppender(caRoot);
a.AddAppender(caA);
@@ -255,7 +259,7 @@
[Test]
public void TestDisable1()
{
- CountingAppender caRoot = new CountingAppender();
+ var caRoot = new CountingAppender();
Logger root = ((Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;
root.AddAppender(caRoot);
@@ -308,8 +312,11 @@
public void TestExists()
{
ILog a = LogManager.GetLogger("a");
+ Assert.IsNotNull(a);
ILog a_b = LogManager.GetLogger("a.b");
+ Assert.IsNotNull(a_b);
ILog a_b_c = LogManager.GetLogger("a.b.c");
+ Assert.IsNotNull(a_b_c);
ILog? t = LogManager.Exists("xx");
Assert.IsNull(t);
@@ -327,7 +334,7 @@
[Test]
public void TestHierarchy1()
{
- Repository.Hierarchy.Hierarchy h = new Repository.Hierarchy.Hierarchy();
+ var h = new Repository.Hierarchy.Hierarchy();
h.Root.Level = Level.Error;
Logger a0 = (Logger)h.GetLogger("a");
@@ -339,4 +346,4 @@
Assert.AreSame(a0, a1);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/log4net.Tests/Util/LogLogTest.cs b/src/log4net.Tests/Util/LogLogTest.cs
index d9fcf4f..4aed3a2 100644
--- a/src/log4net.Tests/Util/LogLogTest.cs
+++ b/src/log4net.Tests/Util/LogLogTest.cs
@@ -19,7 +19,7 @@
*
*/
-using System.Collections;
+using System.Collections.Generic;
using System.Diagnostics;
using log4net.Util;
using NUnit.Framework;
@@ -71,7 +71,7 @@
[Test]
public void LogReceivedAdapter()
{
- ArrayList messages = new ArrayList();
+ var messages = new List<LogLog>();
using (new LogLog.LogReceivedAdapter(messages))
{
@@ -86,26 +86,21 @@
public class TraceListenerCounter : TraceListener
{
- private int count = 0;
-
- public override void Write(string message)
+ public override void Write(string? message)
{
- count++;
+ Count++;
}
- public override void WriteLine(string message)
+ public override void WriteLine(string? message)
{
Write(message);
}
public void Reset()
{
- count = 0;
+ Count = 0;
}
- public int Count
- {
- get { return count; }
- }
+ public int Count { get; private set; }
}
}
diff --git a/src/log4net.Tests/Util/PropertiesDictionaryTest.cs b/src/log4net.Tests/Util/PropertiesDictionaryTest.cs
index 51cf6bf..861b7ac 100644
--- a/src/log4net.Tests/Util/PropertiesDictionaryTest.cs
+++ b/src/log4net.Tests/Util/PropertiesDictionaryTest.cs
@@ -19,6 +19,7 @@
#if NET462_OR_GREATER
+using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
@@ -49,6 +50,8 @@
Assert.AreEqual(10, pd.Count, "Dictionary should have 10 items");
+ Assert.IsNull(pd["notThere"], "Getter should act as IDictionary not IDictionary<TKey, TValue>");
+
// Serialize the properties into a memory stream
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream memory = new MemoryStream();
diff --git a/src/log4net/Config/BasicConfigurator.cs b/src/log4net/Config/BasicConfigurator.cs
index be31939..7af9f90 100644
--- a/src/log4net/Config/BasicConfigurator.cs
+++ b/src/log4net/Config/BasicConfigurator.cs
@@ -19,6 +19,7 @@
using System;
using System.Collections;
+using System.Collections.Generic;
using System.Reflection;
using log4net.Appender;
@@ -49,10 +50,8 @@
/// </remarks>
/// <author>Nicko Cadell</author>
/// <author>Gert Driesen</author>
- public sealed class BasicConfigurator
+ public static class BasicConfigurator
{
- #region Private Static Fields
-
/// <summary>
/// The fully qualified type of the BasicConfigurator class.
/// </summary>
@@ -62,26 +61,6 @@
/// </remarks>
private static readonly Type declaringType = typeof(BasicConfigurator);
- #endregion Private Static Fields
-
- #region Private Instance Constructors
-
- /// <summary>
- /// Initializes a new instance of the <see cref="BasicConfigurator" /> class.
- /// </summary>
- /// <remarks>
- /// <para>
- /// Uses a private access modifier to prevent instantiation of this class.
- /// </para>
- /// </remarks>
- private BasicConfigurator()
- {
- }
-
- #endregion Private Instance Constructors
-
- #region Public Static Methods
-
/// <summary>
/// Initializes the log4net system with a default configuration.
/// </summary>
@@ -96,7 +75,7 @@
/// </remarks>
public static ICollection Configure()
{
- return BasicConfigurator.Configure(LogManager.GetRepository(Assembly.GetCallingAssembly()));
+ return Configure(LogManager.GetRepository(Assembly.GetCallingAssembly()));
}
/// <summary>
@@ -110,7 +89,7 @@
/// </remarks>
public static ICollection Configure(params IAppender[] appenders)
{
- ArrayList configurationMessages = new ArrayList();
+ var configurationMessages = new List<LogLog>();
ILoggerRepository repository = LogManager.GetRepository(Assembly.GetCallingAssembly());
@@ -125,20 +104,6 @@
}
/// <summary>
- /// Initializes the log4net system using the specified appender.
- /// </summary>
- /// <param name="appender">The appender to use to log all logging events.</param>
- /// <remarks>
- /// <para>
- /// Initializes the log4net system using the specified appender.
- /// </para>
- /// </remarks>
- public static ICollection Configure(IAppender appender)
- {
- return Configure(new IAppender[] { appender });
- }
-
- /// <summary>
/// Initializes the <see cref="ILoggerRepository"/> with a default configuration.
/// </summary>
/// <param name="repository">The repository to configure.</param>
@@ -153,18 +118,16 @@
/// </remarks>
public static ICollection Configure(ILoggerRepository repository)
{
- ArrayList configurationMessages = new ArrayList();
+ var configurationMessages = new List<LogLog>();
using (new LogLog.LogReceivedAdapter(configurationMessages))
{
// Create the layout
- PatternLayout layout = new PatternLayout();
- layout.ConversionPattern = PatternLayout.DetailConversionPattern;
+ var layout = new PatternLayout { ConversionPattern = PatternLayout.DetailConversionPattern };
layout.ActivateOptions();
// Create the appender
- ConsoleAppender appender = new ConsoleAppender();
- appender.Layout = layout;
+ var appender = new ConsoleAppender { Layout = layout };
appender.ActivateOptions();
InternalConfigure(repository, appender);
@@ -176,21 +139,6 @@
}
/// <summary>
- /// Initializes the <see cref="ILoggerRepository"/> using the specified appender.
- /// </summary>
- /// <param name="repository">The repository to configure.</param>
- /// <param name="appender">The appender to use to log all logging events.</param>
- /// <remarks>
- /// <para>
- /// Initializes the <see cref="ILoggerRepository"/> using the specified appender.
- /// </para>
- /// </remarks>
- public static ICollection Configure(ILoggerRepository repository, IAppender appender)
- {
- return Configure(repository, new IAppender[] { appender });
- }
-
- /// <summary>
/// Initializes the <see cref="ILoggerRepository"/> using the specified appenders.
/// </summary>
/// <param name="repository">The repository to configure.</param>
@@ -202,7 +150,7 @@
/// </remarks>
public static ICollection Configure(ILoggerRepository repository, params IAppender[] appenders)
{
- ArrayList configurationMessages = new ArrayList();
+ var configurationMessages = new List<LogLog>();
using (new LogLog.LogReceivedAdapter(configurationMessages))
{
@@ -216,17 +164,14 @@
private static void InternalConfigure(ILoggerRepository repository, params IAppender[] appenders)
{
- IBasicRepositoryConfigurator configurableRepository = repository as IBasicRepositoryConfigurator;
- if (configurableRepository != null)
+ if (repository is IBasicRepositoryConfigurator configurableRepository)
{
configurableRepository.Configure(appenders);
}
else
{
- LogLog.Warn(declaringType, "BasicConfigurator: Repository [" + repository + "] does not support the BasicConfigurator");
+ LogLog.Warn(declaringType, $"BasicConfigurator: Repository [{repository}] does not support the BasicConfigurator");
}
}
-
- #endregion Public Static Methods
}
-}
\ No newline at end of file
+}
diff --git a/src/log4net/Config/XmlConfigurator.cs b/src/log4net/Config/XmlConfigurator.cs
index 48f22c3..29ecbab 100644
--- a/src/log4net/Config/XmlConfigurator.cs
+++ b/src/log4net/Config/XmlConfigurator.cs
@@ -20,6 +20,7 @@
using System;
using System.Xml;
using System.Collections;
+using System.Collections.Concurrent;
using System.IO;
using System.Reflection;
using System.Threading;
@@ -27,34 +28,17 @@
using log4net.Util;
using log4net.Repository;
+using System.Collections.Generic;
namespace log4net.Config
{
/// <summary>
- /// Use this class to initialize the log4net environment using an Xml tree.
+ /// Configures a <see cref="ILoggerRepository"/> using an XML tree.
/// </summary>
- /// <remarks>
- /// <para>
- /// Configures a <see cref="ILoggerRepository"/> using an Xml tree.
- /// </para>
- /// </remarks>
/// <author>Nicko Cadell</author>
/// <author>Gert Driesen</author>
- public sealed class XmlConfigurator
+ public static class XmlConfigurator
{
- #region Private Instance Constructors
-
- /// <summary>
- /// Private constructor
- /// </summary>
- private XmlConfigurator()
- {
- }
-
- #endregion Protected Instance Constructors
-
- #region Configure static methods
-
/// <summary>
/// Automatically configures the <see cref="ILoggerRepository"/> using settings
/// stored in the application's configuration file.
@@ -77,7 +61,7 @@
/// <param name="repository">The repository to configure.</param>
public static ICollection Configure(ILoggerRepository repository)
{
- ArrayList configurationMessages = new ArrayList();
+ var configurationMessages = new List<LogLog>();
using (new LogLog.LogReceivedAdapter(configurationMessages))
{
@@ -91,11 +75,11 @@
private static void InternalConfigure(ILoggerRepository repository)
{
- LogLog.Debug(declaringType, "configuring repository [" + repository.Name + "] using .config file section");
+ LogLog.Debug(declaringType, $"configuring repository [{repository.Name}] using .config file section");
try
{
- LogLog.Debug(declaringType, "Application config file is [" + SystemInfo.ConfigurationFileLocation + "]");
+ LogLog.Debug(declaringType, $"Application config file is [{SystemInfo.ConfigurationFileLocation}]");
}
catch
{
@@ -105,8 +89,7 @@
try
{
- XmlElement configElement = System.Configuration.ConfigurationManager.GetSection("log4net") as XmlElement;
- if (configElement == null)
+ if (System.Configuration.ConfigurationManager.GetSection("log4net") is not XmlElement configElement)
{
// Failed to load the xml config using configuration settings handler
LogLog.Error(declaringType, "Failed to find configuration section 'log4net' in the application's .config file. Check your .config file for the <log4net> and <configSections> elements. The configuration section should look like: <section name=\"log4net\" type=\"log4net.Config.Log4NetConfigurationSectionHandler,log4net\" />");
@@ -119,7 +102,7 @@
}
catch (System.Configuration.ConfigurationException confEx)
{
- if (confEx.BareMessage.IndexOf("Unrecognized element") >= 0)
+ if (confEx.BareMessage.IndexOf("Unrecognized element", StringComparison.Ordinal) >= 0)
{
// Looks like the XML file is not valid
LogLog.Error(declaringType, "Failed to parse config file. Check your .config file is well formed XML.", confEx);
@@ -170,7 +153,7 @@
/// <param name="element">The element to parse.</param>
public static ICollection Configure(XmlElement element)
{
- ArrayList configurationMessages = new ArrayList();
+ var configurationMessages = new List<LogLog>();
ILoggerRepository repository = LogManager.GetRepository(Assembly.GetCallingAssembly());
@@ -195,7 +178,7 @@
/// the log4net configuration data.
/// </para>
/// <para>
- /// The log4net configuration file can possible be specified in the application's
+ /// The log4net configuration file can possibly be specified in the application's
/// configuration file (either <c>MyAppName.exe.config</c> for a
/// normal application on <c>Web.config</c> for an ASP.NET application).
/// </para>
@@ -236,7 +219,7 @@
/// </remarks>
public static ICollection Configure(FileInfo configFile)
{
- ArrayList configurationMessages = new ArrayList();
+ var configurationMessages = new List<LogLog>();
using (new LogLog.LogReceivedAdapter(configurationMessages))
{
@@ -262,7 +245,7 @@
/// </remarks>
public static ICollection Configure(Uri configUri)
{
- ArrayList configurationMessages = new ArrayList();
+ var configurationMessages = new List<LogLog>();
ILoggerRepository repository = LogManager.GetRepository(Assembly.GetCallingAssembly());
using (new LogLog.LogReceivedAdapter(configurationMessages))
@@ -291,7 +274,7 @@
/// </remarks>
public static ICollection Configure(Stream configStream)
{
- ArrayList configurationMessages = new ArrayList();
+ var configurationMessages = new List<LogLog>();
ILoggerRepository repository = LogManager.GetRepository(Assembly.GetCallingAssembly());
using (new LogLog.LogReceivedAdapter(configurationMessages))
@@ -316,7 +299,7 @@
/// <param name="element">The element to parse.</param>
public static ICollection Configure(ILoggerRepository repository, XmlElement element)
{
- ArrayList configurationMessages = new ArrayList();
+ var configurationMessages = new List<LogLog>();
using (new LogLog.LogReceivedAdapter(configurationMessages))
{
@@ -343,7 +326,7 @@
/// the configuration data.
/// </para>
/// <para>
- /// The log4net configuration file can possible be specified in the application's
+ /// The log4net configuration file can possibly be specified in the application's
/// configuration file (either <c>MyAppName.exe.config</c> for a
/// normal application on <c>Web.config</c> for an ASP.NET application).
/// </para>
@@ -384,7 +367,7 @@
/// </remarks>
public static ICollection Configure(ILoggerRepository repository, FileInfo configFile)
{
- ArrayList configurationMessages = new ArrayList();
+ var configurationMessages = new List<LogLog>();
using (new LogLog.LogReceivedAdapter(configurationMessages))
{
@@ -396,11 +379,11 @@
return configurationMessages;
}
- private static void InternalConfigure(ILoggerRepository repository, FileInfo configFile)
+ private static void InternalConfigure(ILoggerRepository repository, FileInfo? configFile)
{
- LogLog.Debug(declaringType, "configuring repository [" + repository.Name + "] using file [" + configFile + "]");
+ LogLog.Debug(declaringType, $"configuring repository [{repository.Name}] using file [{configFile}]");
- if (configFile == null)
+ if (configFile is null)
{
LogLog.Error(declaringType, "Configure called with null 'configFile' parameter");
}
@@ -411,7 +394,7 @@
if (File.Exists(configFile.FullName))
{
// Open the file for reading
- FileStream fs = null;
+ FileStream? fs = null;
// Try hard to open the file
for (int retry = 5; --retry >= 0;)
@@ -425,16 +408,16 @@
{
if (retry == 0)
{
- LogLog.Error(declaringType, "Failed to open XML config file [" + configFile.Name + "]", ex);
+ LogLog.Error(declaringType, $"Failed to open XML config file [{configFile.Name}]", ex);
// The stream cannot be valid
fs = null;
}
- System.Threading.Thread.Sleep(250);
+ Thread.Sleep(250);
}
}
- if (fs != null)
+ if (fs is not null)
{
try
{
@@ -473,7 +456,7 @@
/// </remarks>
public static ICollection Configure(ILoggerRepository repository, Uri configUri)
{
- ArrayList configurationMessages = new ArrayList();
+ var configurationMessages = new List<LogLog>();
using (new LogLog.LogReceivedAdapter(configurationMessages))
{
@@ -485,11 +468,11 @@
return configurationMessages;
}
- private static void InternalConfigure(ILoggerRepository repository, Uri configUri)
+ private static void InternalConfigure(ILoggerRepository repository, Uri? configUri)
{
- LogLog.Debug(declaringType, "configuring repository [" + repository.Name + "] using URI [" + configUri + "]");
+ LogLog.Debug(declaringType, $"configuring repository [{repository.Name}] using URI [{configUri}]");
- if (configUri == null)
+ if (configUri is null)
{
LogLog.Error(declaringType, "Configure called with null 'configUri' parameter");
}
@@ -503,7 +486,7 @@
else
{
// NETCF dose not support WebClient
- WebRequest configRequest = null;
+ WebRequest? configRequest = null;
try
{
@@ -511,10 +494,10 @@
}
catch (Exception ex)
{
- LogLog.Error(declaringType, "Failed to create WebRequest for URI [" + configUri + "]", ex);
+ LogLog.Error(declaringType, $"Failed to create WebRequest for URI [{configUri}]", ex);
}
- if (configRequest != null)
+ if (configRequest is not null)
{
// authentication may be required, set client to use default credentials
try
@@ -527,8 +510,8 @@
}
try
{
- using WebResponse response = configRequest.GetResponse();
- if (response != null)
+ using WebResponse? response = configRequest.GetResponse();
+ if (response is not null)
{
using var configStream = response.GetResponseStream();
InternalConfigure(repository, configStream);
@@ -536,7 +519,7 @@
}
catch (Exception ex)
{
- LogLog.Error(declaringType, "Failed to request config from URI [" + configUri + "]", ex);
+ LogLog.Error(declaringType, $"Failed to request config from URI [{configUri}]", ex);
}
}
}
@@ -561,7 +544,7 @@
/// </remarks>
public static ICollection Configure(ILoggerRepository repository, Stream configStream)
{
- ArrayList configurationMessages = new ArrayList();
+ var configurationMessages = new List<LogLog>();
using (new LogLog.LogReceivedAdapter(configurationMessages))
{
@@ -573,22 +556,22 @@
return configurationMessages;
}
- private static void InternalConfigure(ILoggerRepository repository, Stream configStream)
+ private static void InternalConfigure(ILoggerRepository repository, Stream? configStream)
{
- LogLog.Debug(declaringType, "configuring repository [" + repository.Name + "] using stream");
+ LogLog.Debug(declaringType, $"configuring repository [{repository.Name}] using stream");
- if (configStream == null)
+ if (configStream is null)
{
LogLog.Error(declaringType, "Configure called with null 'configStream' parameter");
}
else
{
// Load the config file into a document
- XmlDocument doc = new XmlDocument { XmlResolver = null };
+ XmlDocument? doc = new XmlDocument { XmlResolver = null };
try
{
// Allow the DTD to specify entity includes
- XmlReaderSettings settings = new XmlReaderSettings();
+ var settings = new XmlReaderSettings();
// .NET 4.0 warning CS0618: 'System.Xml.XmlReaderSettings.ProhibitDtd'
// is obsolete: 'Use XmlReaderSettings.DtdProcessing property instead.'
settings.DtdProcessing = DtdProcessing.Ignore;
@@ -607,7 +590,7 @@
doc = null;
}
- if (doc != null)
+ if (doc is not null)
{
LogLog.Debug(declaringType, "loading XML configuration");
@@ -619,7 +602,7 @@
}
else if (configNodeList.Count > 1)
{
- LogLog.Error(declaringType, "XML configuration contains [" + configNodeList.Count + "] <log4net> elements. Only one is allowed. Configuration Aborted.");
+ LogLog.Error(declaringType, $"XML configuration contains [{configNodeList.Count}] <log4net> elements. Only one is allowed. Configuration Aborted.");
}
else
{
@@ -629,10 +612,6 @@
}
}
- #endregion Configure static methods
-
- #region ConfigureAndWatch static methods
-
/// <summary>
/// Configures log4net using the file specified, monitors the file for changes
/// and reloads the configuration if a change is detected.
@@ -656,7 +635,7 @@
/// <seealso cref="M:Configure(FileInfo)"/>
public static ICollection ConfigureAndWatch(FileInfo configFile)
{
- ArrayList configurationMessages = new ArrayList();
+ var configurationMessages = new List<LogLog>();
ILoggerRepository repository = LogManager.GetRepository(Assembly.GetCallingAssembly());
@@ -695,7 +674,7 @@
/// <seealso cref="M:Configure(FileInfo)"/>
public static ICollection ConfigureAndWatch(ILoggerRepository repository, FileInfo configFile)
{
- ArrayList configurationMessages = new ArrayList();
+ var configurationMessages = new List<LogLog>();
using (new LogLog.LogReceivedAdapter(configurationMessages))
{
@@ -707,9 +686,9 @@
return configurationMessages;
}
- private static void InternalConfigureAndWatch(ILoggerRepository repository, FileInfo configFile)
+ private static void InternalConfigureAndWatch(ILoggerRepository repository, FileInfo? configFile)
{
- LogLog.Debug(declaringType, "configuring repository [" + repository.Name + "] using file [" + configFile + "] watching for file updates");
+ LogLog.Debug(declaringType, $"configuring repository [{repository.Name}] using file [{configFile}] watching for file updates");
if (configFile == null)
{
@@ -722,35 +701,26 @@
try
{
- lock (m_repositoryName2ConfigAndWatchHandler)
- {
- // support multiple repositories each having their own watcher
- ConfigureAndWatchHandler handler =
- (ConfigureAndWatchHandler)m_repositoryName2ConfigAndWatchHandler[configFile.FullName];
-
- if (handler != null)
+ // Support multiple repositories each having their own watcher.
+ // Create and start a watch handler that will reload the
+ // configuration whenever the config file is modified.
+ m_repositoryName2ConfigAndWatchHandler.AddOrUpdate(
+ configFile.FullName,
+ _ => new ConfigureAndWatchHandler(repository, configFile),
+ (_, handler) =>
{
- m_repositoryName2ConfigAndWatchHandler.Remove(configFile.FullName);
+ // Replace the old handler.
handler.Dispose();
- }
-
- // Create and start a watch handler that will reload the
- // configuration whenever the config file is modified.
- handler = new ConfigureAndWatchHandler(repository, configFile);
- m_repositoryName2ConfigAndWatchHandler[configFile.FullName] = handler;
- }
+ return new ConfigureAndWatchHandler(repository, configFile);
+ });
}
catch (Exception ex)
{
- LogLog.Error(declaringType, "Failed to initialize configuration file watcher for file [" + configFile.FullName + "]", ex);
+ LogLog.Error(declaringType, $"Failed to initialize configuration file watcher for file [{configFile.FullName}]", ex);
}
}
}
- #endregion ConfigureAndWatch static methods
-
- #region ConfigureAndWatchHandler
-
/// <summary>
/// Class used to watch config files.
/// </summary>
@@ -772,17 +742,17 @@
/// <summary>
/// Holds the FileInfo used to configure the XmlConfigurator
/// </summary>
- private FileInfo m_configFile;
+ private readonly FileInfo m_configFile;
/// <summary>
/// Holds the repository being configured.
/// </summary>
- private ILoggerRepository m_repository;
+ private readonly ILoggerRepository m_repository;
/// <summary>
/// The timer used to compress the notification events.
/// </summary>
- private Timer m_timer;
+ private readonly Timer m_timer;
/// <summary>
/// The default amount of time to wait after receiving notification
@@ -794,7 +764,7 @@
/// Watches file for changes. This object should be disposed when no longer
/// needed to free system handles on the watched resources.
/// </summary>
- private FileSystemWatcher m_watcher;
+ private readonly FileSystemWatcher m_watcher;
/// <summary>
/// Initializes a new instance of the <see cref="ConfigureAndWatchHandler" /> class to
@@ -814,25 +784,24 @@
m_configFile = configFile;
// Create a new FileSystemWatcher and set its properties.
- m_watcher = new FileSystemWatcher();
-
- m_watcher.Path = m_configFile.DirectoryName;
- m_watcher.Filter = m_configFile.Name;
-
- // Set the notification filters
- m_watcher.NotifyFilter = NotifyFilters.CreationTime | NotifyFilters.LastWrite | NotifyFilters.FileName;
+ m_watcher = new FileSystemWatcher()
+ {
+ Path = m_configFile.DirectoryName,
+ Filter = m_configFile.Name,
+ NotifyFilter = NotifyFilters.CreationTime | NotifyFilters.LastWrite | NotifyFilters.FileName,
+ };
// Add event handlers. OnChanged will do for all event handlers that fire a FileSystemEventArgs
- m_watcher.Changed += new FileSystemEventHandler(ConfigureAndWatchHandler_OnChanged);
- m_watcher.Created += new FileSystemEventHandler(ConfigureAndWatchHandler_OnChanged);
- m_watcher.Deleted += new FileSystemEventHandler(ConfigureAndWatchHandler_OnChanged);
- m_watcher.Renamed += new RenamedEventHandler(ConfigureAndWatchHandler_OnRenamed);
+ m_watcher.Changed += ConfigureAndWatchHandler_OnChanged;
+ m_watcher.Created += ConfigureAndWatchHandler_OnChanged;
+ m_watcher.Deleted += ConfigureAndWatchHandler_OnChanged;
+ m_watcher.Renamed += ConfigureAndWatchHandler_OnRenamed;
// Begin watching.
m_watcher.EnableRaisingEvents = true;
// Create the timer that will be used to deliver events. Set as disabled
- m_timer = new Timer(new TimerCallback(OnWatchedFileChange), null, Timeout.Infinite, Timeout.Infinite);
+ m_timer = new Timer(OnWatchedFileChange, state: null, Timeout.Infinite, Timeout.Infinite);
}
/// <summary>
@@ -847,7 +816,7 @@
/// </remarks>
private void ConfigureAndWatchHandler_OnChanged(object source, FileSystemEventArgs e)
{
- LogLog.Debug(declaringType, "ConfigureAndWatchHandler: " + e.ChangeType + " [" + m_configFile.FullName + "]");
+ LogLog.Debug(declaringType, $"ConfigureAndWatchHandler: {e.ChangeType} [{m_configFile.FullName}]");
// Deliver the event in TimeoutMillis time
// timer will fire only once
@@ -866,7 +835,7 @@
/// </remarks>
private void ConfigureAndWatchHandler_OnRenamed(object source, RenamedEventArgs e)
{
- LogLog.Debug(declaringType, "ConfigureAndWatchHandler: " + e.ChangeType + " [" + m_configFile.FullName + "]");
+ LogLog.Debug(declaringType, $"ConfigureAndWatchHandler: {e.ChangeType} [{m_configFile.FullName}]");
// Deliver the event in TimeoutMillis time
// timer will fire only once
@@ -894,10 +863,6 @@
}
}
- #endregion ConfigureAndWatchHandler
-
- #region Private Static Methods
-
/// <summary>
/// Configures the specified repository using a <c>log4net</c> element.
/// </summary>
@@ -913,13 +878,13 @@
/// to load the configuration from an <see cref="XmlElement"/>.
/// </para>
/// </remarks>
- private static void InternalConfigureFromXml(ILoggerRepository repository, XmlElement element)
+ private static void InternalConfigureFromXml(ILoggerRepository? repository, XmlElement? element)
{
- if (element == null)
+ if (element is null)
{
LogLog.Error(declaringType, "ConfigureFromXml called with null 'element' parameter");
}
- else if (repository == null)
+ else if (repository is null)
{
LogLog.Error(declaringType, "ConfigureFromXml called with null 'repository' parameter");
}
@@ -927,8 +892,7 @@
{
LogLog.Debug(declaringType, "Configuring Repository [" + repository.Name + "]");
- IXmlRepositoryConfigurator configurableRepository = repository as IXmlRepositoryConfigurator;
- if (configurableRepository == null)
+ if (repository is not IXmlRepositoryConfigurator configurableRepository)
{
LogLog.Warn(declaringType, "Repository [" + repository + "] does not support the XmlConfigurator");
}
@@ -946,16 +910,12 @@
}
}
- #endregion Private Static Methods
-
- #region Private Static Fields
-
/// <summary>
/// Maps repository names to ConfigAndWatchHandler instances to allow a particular
/// ConfigAndWatchHandler to dispose of its FileSystemWatcher when a repository is
/// reconfigured.
/// </summary>
- private static readonly Hashtable m_repositoryName2ConfigAndWatchHandler = new Hashtable();
+ private static readonly ConcurrentDictionary<string, ConfigureAndWatchHandler> m_repositoryName2ConfigAndWatchHandler = new(StringComparer.Ordinal);
/// <summary>
/// The fully qualified type of the XmlConfigurator class.
@@ -965,7 +925,5 @@
/// log message.
/// </remarks>
private static readonly Type declaringType = typeof(XmlConfigurator);
-
- #endregion Private Static Fields
}
-}
\ No newline at end of file
+}
diff --git a/src/log4net/Config/XmlConfiguratorAttribute.cs b/src/log4net/Config/XmlConfiguratorAttribute.cs
index b6d6c24..3579cda 100644
--- a/src/log4net/Config/XmlConfiguratorAttribute.cs
+++ b/src/log4net/Config/XmlConfiguratorAttribute.cs
@@ -18,7 +18,7 @@
#endregion
using System;
-using System.Collections;
+using System.Collections.Generic;
using System.Reflection;
using System.IO;
@@ -26,6 +26,8 @@
using log4net.Repository;
using log4net.Repository.Hierarchy;
+#nullable enable
+
namespace log4net.Config
{
/// <summary>
@@ -95,8 +97,6 @@
{
}
- #region Public Instance Properties
-
/// <summary>
/// Gets or sets the filename of the configuration file.
/// </summary>
@@ -113,18 +113,11 @@
/// The <see cref="ConfigFile"/> takes priority over the <see cref="ConfigFileExtension"/>.
/// </para>
/// </remarks>
- public string ConfigFile
- {
- get { return m_configFile; }
- set { m_configFile = value; }
- }
+ public string? ConfigFile { get; set; }
/// <summary>
/// Gets or sets the extension of the configuration file.
/// </summary>
- /// <value>
- /// The extension of the configuration file.
- /// </value>
/// <remarks>
/// <para>
/// If specified this is the extension for the configuration file.
@@ -141,11 +134,7 @@
/// The <see cref="ConfigFile"/> takes priority over the <see cref="ConfigFileExtension"/>.
/// </para>
/// </remarks>
- public string ConfigFileExtension
- {
- get { return m_configFileExtension; }
- set { m_configFileExtension = value; }
- }
+ public string? ConfigFileExtension { get; set; }
/// <summary>
/// Gets or sets a value indicating whether to watch the configuration file.
@@ -169,15 +158,7 @@
/// Watching configuration is not supported on the SSCLI.
/// </note>
/// </remarks>
- public bool Watch
- {
- get { return m_configureAndWatch; }
- set { m_configureAndWatch = value; }
- }
-
- #endregion Public Instance Properties
-
- #region Override ConfiguratorAttribute
+ public bool Watch { get; set; }
/// <summary>
/// Configures the <see cref="ILoggerRepository"/> for the specified assembly.
@@ -195,11 +176,11 @@
/// <exception cref="ArgumentOutOfRangeException">The <paramref name="targetRepository" /> does not extend <see cref="Hierarchy"/>.</exception>
public override void Configure(Assembly sourceAssembly, ILoggerRepository targetRepository)
{
- IList configurationMessages = new ArrayList();
+ var configurationMessages = new List<LogLog>();
using (new LogLog.LogReceivedAdapter(configurationMessages))
{
- string applicationBaseDirectory = null;
+ string? applicationBaseDirectory = null;
try
{
applicationBaseDirectory = SystemInfo.ApplicationBaseDirectory;
@@ -210,21 +191,19 @@
// and the application does not have PathDiscovery permission
}
- if (applicationBaseDirectory == null || (new Uri(applicationBaseDirectory)).IsFile)
+ if (applicationBaseDirectory is null || (new Uri(applicationBaseDirectory)).IsFile)
{
ConfigureFromFile(sourceAssembly, targetRepository);
}
else
{
- ConfigureFromUri(sourceAssembly, targetRepository);
+ ConfigureFromUri(targetRepository);
}
}
targetRepository.ConfigurationMessages = configurationMessages;
}
- #endregion
-
/// <summary>
/// Attempt to load configuration from the local file system
/// </summary>
@@ -233,12 +212,12 @@
private void ConfigureFromFile(Assembly sourceAssembly, ILoggerRepository targetRepository)
{
// Work out the full path to the config file
- string fullPath2ConfigFile = null;
+ string? fullPath2ConfigFile = null;
// Select the config file
- if (m_configFile == null || m_configFile.Length == 0)
+ if (string.IsNullOrEmpty(ConfigFile))
{
- if (m_configFileExtension == null || m_configFileExtension.Length == 0)
+ if (string.IsNullOrEmpty(ConfigFileExtension))
{
// Use the default .config file for the AppDomain
try
@@ -253,12 +232,12 @@
else
{
// Force the extension to start with a '.'
- if (m_configFileExtension[0] != '.')
+ if (ConfigFileExtension![0] != '.')
{
- m_configFileExtension = "." + m_configFileExtension;
+ ConfigFileExtension = '.' + ConfigFileExtension;
}
- string applicationBaseDirectory = null;
+ string? applicationBaseDirectory = null;
try
{
applicationBaseDirectory = SystemInfo.ApplicationBaseDirectory;
@@ -268,36 +247,36 @@
LogLog.Error(declaringType, "Exception getting ApplicationBaseDirectory. Must be able to resolve ApplicationBaseDirectory and AssemblyFileName when ConfigFileExtension property is set.", ex);
}
- if (applicationBaseDirectory != null)
+ if (applicationBaseDirectory is not null)
{
- fullPath2ConfigFile = Path.Combine(applicationBaseDirectory, SystemInfo.AssemblyFileName(sourceAssembly) + m_configFileExtension);
+ fullPath2ConfigFile = Path.Combine(applicationBaseDirectory, SystemInfo.AssemblyFileName(sourceAssembly) + ConfigFileExtension);
}
}
}
else
{
- string applicationBaseDirectory = null;
+ string? applicationBaseDirectory = null;
try
{
applicationBaseDirectory = SystemInfo.ApplicationBaseDirectory;
}
catch (Exception ex)
{
- LogLog.Warn(declaringType, "Exception getting ApplicationBaseDirectory. ConfigFile property path [" + m_configFile + "] will be treated as an absolute path.", ex);
+ LogLog.Warn(declaringType, $"Exception getting ApplicationBaseDirectory. ConfigFile property path [{ConfigFile}] will be treated as an absolute path.", ex);
}
- if (applicationBaseDirectory != null)
+ if (applicationBaseDirectory is not null)
{
// Just the base dir + the config file
- fullPath2ConfigFile = Path.Combine(applicationBaseDirectory, m_configFile);
+ fullPath2ConfigFile = Path.Combine(applicationBaseDirectory, ConfigFile!);
}
else
{
- fullPath2ConfigFile = m_configFile;
+ fullPath2ConfigFile = ConfigFile;
}
}
- if (fullPath2ConfigFile != null)
+ if (fullPath2ConfigFile is not null)
{
ConfigureFromFile(targetRepository, new FileInfo(fullPath2ConfigFile));
}
@@ -311,7 +290,7 @@
private void ConfigureFromFile(ILoggerRepository targetRepository, FileInfo configFile)
{
// Do we configure just once or do we configure and then watch?
- if (m_configureAndWatch)
+ if (Watch)
{
XmlConfigurator.ConfigureAndWatch(targetRepository, configFile);
}
@@ -324,19 +303,18 @@
/// <summary>
/// Attempt to load configuration from a URI
/// </summary>
- /// <param name="sourceAssembly">The assembly that this attribute was defined on.</param>
/// <param name="targetRepository">The repository to configure.</param>
- private void ConfigureFromUri(Assembly sourceAssembly, ILoggerRepository targetRepository)
+ private void ConfigureFromUri(ILoggerRepository targetRepository)
{
// Work out the full path to the config file
- Uri fullPath2ConfigFile = null;
+ Uri? fullPath2ConfigFile = null;
// Select the config file
- if (m_configFile == null || m_configFile.Length == 0)
+ if (string.IsNullOrEmpty(ConfigFile))
{
- if (m_configFileExtension == null || m_configFileExtension.Length == 0)
+ if (string.IsNullOrEmpty(ConfigFileExtension))
{
- string systemConfigFilePath = null;
+ string? systemConfigFilePath = null;
try
{
systemConfigFilePath = SystemInfo.ConfigurationFileLocation;
@@ -346,23 +324,21 @@
LogLog.Error(declaringType, "XmlConfiguratorAttribute: Exception getting ConfigurationFileLocation. Must be able to resolve ConfigurationFileLocation when ConfigFile and ConfigFileExtension properties are not set.", ex);
}
- if (systemConfigFilePath != null)
+ if (systemConfigFilePath is not null)
{
- Uri systemConfigFileUri = new Uri(systemConfigFilePath);
-
// Use the default .config file for the AppDomain
- fullPath2ConfigFile = systemConfigFileUri;
+ fullPath2ConfigFile = new Uri(systemConfigFilePath);
}
}
else
{
// Force the extension to start with a '.'
- if (m_configFileExtension[0] != '.')
+ if (ConfigFileExtension![0] != '.')
{
- m_configFileExtension = "." + m_configFileExtension;
+ ConfigFileExtension = '.' + ConfigFileExtension;
}
- string systemConfigFilePath = null;
+ string? systemConfigFilePath = null;
try
{
systemConfigFilePath = SystemInfo.ConfigurationFileLocation;
@@ -372,18 +348,18 @@
LogLog.Error(declaringType, "XmlConfiguratorAttribute: Exception getting ConfigurationFileLocation. Must be able to resolve ConfigurationFileLocation when the ConfigFile property are not set.", ex);
}
- if (systemConfigFilePath != null)
+ if (systemConfigFilePath is not null)
{
- UriBuilder builder = new UriBuilder(new Uri(systemConfigFilePath));
+ var builder = new UriBuilder(new Uri(systemConfigFilePath));
// Remove the current extension from the systemConfigFileUri path
string path = builder.Path;
- int startOfExtension = path.LastIndexOf(".");
+ int startOfExtension = path.LastIndexOf('.');
if (startOfExtension >= 0)
{
path = path.Substring(0, startOfExtension);
}
- path += m_configFileExtension;
+ path += ConfigFileExtension;
builder.Path = path;
fullPath2ConfigFile = builder.Uri;
@@ -392,38 +368,38 @@
}
else
{
- string applicationBaseDirectory = null;
+ string? applicationBaseDirectory = null;
try
{
applicationBaseDirectory = SystemInfo.ApplicationBaseDirectory;
}
catch (Exception ex)
{
- LogLog.Warn(declaringType, "Exception getting ApplicationBaseDirectory. ConfigFile property path [" + m_configFile + "] will be treated as an absolute URI.", ex);
+ LogLog.Warn(declaringType, $"Exception getting ApplicationBaseDirectory. ConfigFile property path [{ConfigFile}] will be treated as an absolute URI.", ex);
}
- if (applicationBaseDirectory != null)
+ if (applicationBaseDirectory is not null)
{
// Just the base dir + the config file
- fullPath2ConfigFile = new Uri(new Uri(applicationBaseDirectory), m_configFile);
+ fullPath2ConfigFile = new Uri(new Uri(applicationBaseDirectory), ConfigFile!);
}
else
{
- fullPath2ConfigFile = new Uri(m_configFile);
+ fullPath2ConfigFile = new Uri(ConfigFile!);
}
}
- if (fullPath2ConfigFile != null)
+ if (fullPath2ConfigFile is not null)
{
if (fullPath2ConfigFile.IsFile)
{
- // The m_configFile could be an absolute local path, therefore we have to be
+ // The ConfigFile could be an absolute local path, therefore we have to be
// prepared to switch back to using FileInfos here
ConfigureFromFile(targetRepository, new FileInfo(fullPath2ConfigFile.LocalPath));
}
else
{
- if (m_configureAndWatch)
+ if (Watch)
{
LogLog.Warn(declaringType, "XmlConfiguratorAttribute: Unable to watch config file loaded from a URI");
}
@@ -432,16 +408,6 @@
}
}
- #region Private Instance Fields
-
- private string m_configFile = null;
- private string m_configFileExtension = null;
- private bool m_configureAndWatch = false;
-
- #endregion Private Instance Fields
-
- #region Private Static Fields
-
/// <summary>
/// The fully qualified type of the XmlConfiguratorAttribute class.
/// </summary>
@@ -450,7 +416,5 @@
/// log message.
/// </remarks>
private static readonly Type declaringType = typeof(XmlConfiguratorAttribute);
-
- #endregion Private Static Fields
}
-}
\ No newline at end of file
+}
diff --git a/src/log4net/Core/IFixingRequired.cs b/src/log4net/Core/IFixingRequired.cs
index 58e84cf..2251135 100644
--- a/src/log4net/Core/IFixingRequired.cs
+++ b/src/log4net/Core/IFixingRequired.cs
@@ -17,8 +17,6 @@
//
#endregion
-using System;
-
namespace log4net.Core
{
/// <summary>
@@ -53,6 +51,6 @@
/// and logged from any thread with identical results.
/// </para>
/// </remarks>
- object GetFixedObject();
+ object? GetFixedObject();
}
}
diff --git a/src/log4net/Core/ILoggerWrapper.cs b/src/log4net/Core/ILoggerWrapper.cs
index fefbd20..3edde25 100644
--- a/src/log4net/Core/ILoggerWrapper.cs
+++ b/src/log4net/Core/ILoggerWrapper.cs
@@ -17,12 +17,6 @@
//
#endregion
-using System;
-
-using log4net;
-using log4net.Core;
-using log4net.Repository;
-
namespace log4net.Core
{
/// <summary>
@@ -40,18 +34,14 @@
public interface ILoggerWrapper
{
/// <summary>
- /// Get the implementation behind this wrapper object.
+ /// Gets the <see cref="ILogger"/> object that implements this object.
/// </summary>
/// <value>
- /// The <see cref="ILogger"/> object that in implementing this object.
/// </value>
/// <remarks>
/// <para>
- /// The <see cref="ILogger"/> object that in implementing this
- /// object. The <c>Logger</c> object may not
- /// be the same object as this object because of logger decorators.
- /// This gets the actual underlying objects that is used to process
- /// the log events.
+ /// The <c>Logger</c> object may not be the same object as this object because of logger decorators.
+ /// This gets the actual underlying objects that is used to process the log events.
/// </para>
/// </remarks>
ILogger Logger { get; }
diff --git a/src/log4net/Core/IOptionHandler.cs b/src/log4net/Core/IOptionHandler.cs
index 6d73ee1..aadf71c 100644
--- a/src/log4net/Core/IOptionHandler.cs
+++ b/src/log4net/Core/IOptionHandler.cs
@@ -17,8 +17,6 @@
//
#endregion
-using System;
-
namespace log4net.Core
{
/// <summary>
diff --git a/src/log4net/Core/LocationInfo.cs b/src/log4net/Core/LocationInfo.cs
index 5e8295e..a05adca 100644
--- a/src/log4net/Core/LocationInfo.cs
+++ b/src/log4net/Core/LocationInfo.cs
@@ -59,8 +59,6 @@
[Serializable]
public class LocationInfo
{
- #region Public Instance Constructors
-
/// <summary>
/// Constructor
/// </summary>
@@ -72,16 +70,16 @@
/// class based on the current thread.
/// </para>
/// </remarks>
- public LocationInfo(Type callerStackBoundaryDeclaringType)
+ public LocationInfo(Type? callerStackBoundaryDeclaringType)
{
// Initialize all fields
- m_className = NA;
- m_fileName = NA;
- m_lineNumber = NA;
- m_methodName = NA;
- m_fullInfo = NA;
+ ClassName = NA;
+ FileName = NA;
+ LineNumber = NA;
+ MethodName = NA;
+ FullInfo = NA;
- if (callerStackBoundaryDeclaringType != null)
+ if (callerStackBoundaryDeclaringType is not null)
{
try
{
@@ -114,35 +112,35 @@
{
// take into account the frames we skip above
int adjustedFrameCount = st.FrameCount - frameIndex;
- ArrayList stackFramesList = new ArrayList(adjustedFrameCount);
- m_stackFrames = new StackFrameItem[adjustedFrameCount];
+ ArrayList stackFramesList = new ArrayList(adjustedFrameCount);
+ StackFrames = new StackFrameItem[adjustedFrameCount];
for (int i=frameIndex; i < st.FrameCount; i++)
{
stackFramesList.Add(new StackFrameItem(st.GetFrame(i)));
}
- stackFramesList.CopyTo(m_stackFrames, 0);
+ stackFramesList.CopyTo(StackFrames, 0);
// now frameIndex is the first 'user' caller frame
StackFrame locationFrame = st.GetFrame(frameIndex);
- if (locationFrame != null)
+ if (locationFrame is not null)
{
System.Reflection.MethodBase method = locationFrame.GetMethod();
- if (method != null)
+ if (method is not null)
{
- m_methodName = method.Name;
- if (method.DeclaringType != null)
+ MethodName = method.Name;
+ if (method.DeclaringType is not null)
{
- m_className = method.DeclaringType.FullName;
+ ClassName = method.DeclaringType.FullName;
}
}
- m_fileName = locationFrame.GetFileName();
- m_lineNumber = locationFrame.GetFileLineNumber().ToString(System.Globalization.NumberFormatInfo.InvariantInfo);
+ FileName = locationFrame.GetFileName();
+ LineNumber = locationFrame.GetFileLineNumber().ToString(System.Globalization.NumberFormatInfo.InvariantInfo);
// Combine all location info
- m_fullInfo = m_className + '.' + m_methodName + '(' + m_fileName + ':' + m_lineNumber + ')';
+ FullInfo = ClassName + '.' + MethodName + '(' + FileName + ':' + LineNumber + ')';
}
}
}
@@ -170,84 +168,33 @@
/// </remarks>
public LocationInfo(string className, string methodName, string fileName, string lineNumber)
{
- m_className = className;
- m_fileName = fileName;
- m_lineNumber = lineNumber;
- m_methodName = methodName;
- m_fullInfo = m_className + '.' + m_methodName + '(' + m_fileName +
- ':' + m_lineNumber + ')';
+ ClassName = className;
+ FileName = fileName;
+ LineNumber = lineNumber;
+ MethodName = methodName;
+ FullInfo = $"{ClassName}.{MethodName}({FileName}:{LineNumber})";
}
- #endregion Public Instance Constructors
-
- #region Public Instance Properties
-
/// <summary>
/// Gets the fully qualified class name of the caller making the logging
/// request.
/// </summary>
- /// <value>
- /// The fully qualified class name of the caller making the logging
- /// request.
- /// </value>
- /// <remarks>
- /// <para>
- /// Gets the fully qualified class name of the caller making the logging
- /// request.
- /// </para>
- /// </remarks>
- public string ClassName
- {
- get { return m_className; }
- }
+ public string? ClassName { get; }
/// <summary>
/// Gets the file name of the caller.
/// </summary>
- /// <value>
- /// The file name of the caller.
- /// </value>
- /// <remarks>
- /// <para>
- /// Gets the file name of the caller.
- /// </para>
- /// </remarks>
- public string FileName
- {
- get { return m_fileName; }
- }
+ public string? FileName { get; }
/// <summary>
/// Gets the line number of the caller.
/// </summary>
- /// <value>
- /// The line number of the caller.
- /// </value>
- /// <remarks>
- /// <para>
- /// Gets the line number of the caller.
- /// </para>
- /// </remarks>
- public string LineNumber
- {
- get { return m_lineNumber; }
- }
+ public string LineNumber { get; }
/// <summary>
/// Gets the method name of the caller.
/// </summary>
- /// <value>
- /// The method name of the caller.
- /// </value>
- /// <remarks>
- /// <para>
- /// Gets the method name of the caller.
- /// </para>
- /// </remarks>
- public string MethodName
- {
- get { return m_methodName; }
- }
+ public string MethodName { get; }
/// <summary>
/// Gets all available caller information
@@ -262,42 +209,21 @@
/// <c>fully.qualified.classname.of.caller.methodName(Filename:line)</c>
/// </para>
/// </remarks>
- public string FullInfo
- {
- get { return m_fullInfo; }
- }
-
+ public string FullInfo { get; }
+
/// <summary>
/// Gets the stack frames from the stack trace of the caller making the log request
/// </summary>
- public StackFrameItem[] StackFrames
- {
- get { return m_stackFrames; }
- }
+ public StackFrameItem[]? StackFrames { get; }
- #endregion Public Instance Properties
-
- #region Private Instance Fields
-
- private readonly string m_className;
- private readonly string m_fileName;
- private readonly string m_lineNumber;
- private readonly string m_methodName;
- private readonly string m_fullInfo;
- private readonly StackFrameItem[] m_stackFrames;
-
- #endregion Private Instance Fields
-
- #region Private Static Fields
-
- /// <summary>
- /// The fully qualified type of the LocationInfo class.
- /// </summary>
- /// <remarks>
- /// Used by the internal logger to record the Type of the
- /// log message.
- /// </remarks>
- private static readonly Type declaringType = typeof(LocationInfo);
+ /// <summary>
+ /// The fully qualified type of the LocationInfo class.
+ /// </summary>
+ /// <remarks>
+ /// Used by the internal logger to record the Type of the
+ /// log message.
+ /// </remarks>
+ private static readonly Type declaringType = typeof(LocationInfo);
/// <summary>
/// When location information is not available the constant
@@ -305,7 +231,5 @@
/// constant is <b>?</b>.
/// </summary>
private const string NA = "?";
-
- #endregion Private Static Fields
}
}
diff --git a/src/log4net/Core/LoggerManager.cs b/src/log4net/Core/LoggerManager.cs
index e09b422..0a9a691 100644
--- a/src/log4net/Core/LoggerManager.cs
+++ b/src/log4net/Core/LoggerManager.cs
@@ -18,12 +18,13 @@
#endregion
using System;
-using System.Runtime.InteropServices;
using System.Reflection;
-
+using System.Text;
using log4net.Util;
using log4net.Repository;
+#nullable enable
+
namespace log4net.Core
{
/// <summary>
@@ -34,7 +35,7 @@
/// Static manager that controls the creation of repositories
/// </para>
/// <para>
- /// This class is used by the wrapper managers (e.g. <see cref="log4net.LogManager"/>)
+ /// This class is used by the wrapper managers (e.g. <see cref="LogManager"/>)
/// to provide access to the <see cref="ILogger"/> objects.
/// </para>
/// <para>
@@ -47,26 +48,8 @@
/// </remarks>
/// <author>Nicko Cadell</author>
/// <author>Gert Driesen</author>
- public sealed class LoggerManager
+ public static class LoggerManager
{
- #region Private Instance Constructors
-
- /// <summary>
- /// Private constructor to prevent instances. Only static methods should be used.
- /// </summary>
- /// <remarks>
- /// <para>
- /// Private constructor to prevent instances. Only static methods should be used.
- /// </para>
- /// </remarks>
- private LoggerManager()
- {
- }
-
- #endregion Private Instance Constructors
-
- #region Static Constructor
-
/// <summary>
/// Hook the shutdown event
/// </summary>
@@ -74,7 +57,7 @@
/// <para>
/// On the full .NET runtime, the static constructor hooks up the
/// <c>AppDomain.ProcessExit</c> and <c>AppDomain.DomainUnload</c>> events.
- /// These are used to shutdown the log4net system as the application exits.
+ /// These are used to shut down the log4net system as the application exits.
/// </para>
/// </remarks>
static LoggerManager()
@@ -99,48 +82,45 @@
// Set the default repository selector
// Look for the RepositorySelector type specified in the AppSettings 'log4net.RepositorySelector'
- string appRepositorySelectorTypeName = SystemInfo.GetAppSetting("log4net.RepositorySelector");
- if (appRepositorySelectorTypeName != null && appRepositorySelectorTypeName.Length > 0)
+ string? appRepositorySelectorTypeName = SystemInfo.GetAppSetting("log4net.RepositorySelector");
+ if (!string.IsNullOrEmpty(appRepositorySelectorTypeName))
{
// Resolve the config string into a Type
- Type appRepositorySelectorType = null;
+ Type? appRepositorySelectorType = null;
try
{
- appRepositorySelectorType = SystemInfo.GetTypeFromString(appRepositorySelectorTypeName, false, true);
+ appRepositorySelectorType = SystemInfo.GetTypeFromString(appRepositorySelectorTypeName!, false, true);
}
catch (Exception ex)
{
- LogLog.Error(declaringType, "Exception while resolving RepositorySelector Type [" + appRepositorySelectorTypeName + "]", ex);
+ LogLog.Error(declaringType, $"Exception while resolving RepositorySelector Type [{appRepositorySelectorTypeName}]", ex);
}
- if (appRepositorySelectorType != null)
+ if (appRepositorySelectorType is not null)
{
// Create an instance of the RepositorySelectorType
- object appRepositorySelectorObj = null;
+ object? appRepositorySelectorObj = null;
try
{
appRepositorySelectorObj = Activator.CreateInstance(appRepositorySelectorType);
}
catch (Exception ex)
{
- LogLog.Error(declaringType, "Exception while creating RepositorySelector [" + appRepositorySelectorType.FullName + "]", ex);
+ LogLog.Error(declaringType, $"Exception while creating RepositorySelector [{appRepositorySelectorType.FullName}]", ex);
}
- if (appRepositorySelectorObj != null && appRepositorySelectorObj is IRepositorySelector)
+ if (appRepositorySelectorObj is IRepositorySelector sel)
{
- RepositorySelector = (IRepositorySelector)appRepositorySelectorObj;
+ RepositorySelector = sel;
}
else
{
- LogLog.Error(declaringType, "RepositorySelector Type [" + appRepositorySelectorType.FullName + "] is not an IRepositorySelector");
+ LogLog.Error(declaringType, $"RepositorySelector Type [{appRepositorySelectorType.FullName}] is not an IRepositorySelector");
}
}
}
// Create the DefaultRepositorySelector if not configured above
- if (RepositorySelector == null)
- {
- RepositorySelector = new DefaultRepositorySelector(typeof(log4net.Repository.Hierarchy.Hierarchy));
- }
+ RepositorySelector ??= new DefaultRepositorySelector(typeof(Repository.Hierarchy.Hierarchy));
}
/// <summary>
@@ -158,16 +138,12 @@
private static void RegisterAppDomainEvents()
{
// ProcessExit seems to be fired if we are part of the default domain
- AppDomain.CurrentDomain.ProcessExit += new EventHandler(OnProcessExit);
+ AppDomain.CurrentDomain.ProcessExit += OnProcessExit;
// Otherwise DomainUnload is fired
- AppDomain.CurrentDomain.DomainUnload += new EventHandler(OnDomainUnload);
+ AppDomain.CurrentDomain.DomainUnload += OnDomainUnload;
}
- #endregion Static Constructor
-
- #region Public Static Methods
-
/// <summary>
/// Return the default <see cref="ILoggerRepository"/> instance.
/// </summary>
@@ -188,7 +164,7 @@
/// <summary>
/// Returns the default <see cref="ILoggerRepository"/> instance.
/// </summary>
- /// <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ /// <param name="repositoryAssembly">The assembly to use to look up the repository.</param>
/// <returns>The default <see cref="ILoggerRepository"/> instance.</returns>
[Obsolete("Use GetRepository instead of GetLoggerRepository")]
public static ILoggerRepository GetLoggerRepository(Assembly repositoryAssembly)
@@ -209,9 +185,9 @@
/// </remarks>
public static ILoggerRepository GetRepository(string repository)
{
- if (repository == null)
+ if (repository is null)
{
- throw new ArgumentNullException("repository");
+ throw new ArgumentNullException(nameof(repository));
}
return RepositorySelector.GetRepository(repository);
}
@@ -219,7 +195,7 @@
/// <summary>
/// Returns the default <see cref="ILoggerRepository"/> instance.
/// </summary>
- /// <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ /// <param name="repositoryAssembly">The assembly to use to look up the repository.</param>
/// <returns>The default <see cref="ILoggerRepository"/> instance.</returns>
/// <remarks>
/// <para>
@@ -228,9 +204,9 @@
/// </remarks>
public static ILoggerRepository GetRepository(Assembly repositoryAssembly)
{
- if (repositoryAssembly == null)
+ if (repositoryAssembly is null)
{
- throw new ArgumentNullException("repositoryAssembly");
+ throw new ArgumentNullException(nameof(repositoryAssembly));
}
return RepositorySelector.GetRepository(repositoryAssembly);
}
@@ -251,15 +227,15 @@
/// <c>null</c>.
/// </para>
/// </remarks>
- public static ILogger Exists(string repository, string name)
+ public static ILogger? Exists(string repository, string name)
{
- if (repository == null)
+ if (repository is null)
{
- throw new ArgumentNullException("repository");
+ throw new ArgumentNullException(nameof(repository));
}
- if (name == null)
+ if (name is null)
{
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
}
return RepositorySelector.GetRepository(repository).Exists(name);
}
@@ -267,7 +243,7 @@
/// <summary>
/// Returns the named logger if it exists.
/// </summary>
- /// <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ /// <param name="repositoryAssembly">The assembly to use to look up the repository.</param>
/// <param name="name">The fully qualified logger name to look for.</param>
/// <returns>
/// The logger found, or <c>null</c> if the named logger does not exist in the
@@ -280,15 +256,15 @@
/// <c>null</c>.
/// </para>
/// </remarks>
- public static ILogger Exists(Assembly repositoryAssembly, string name)
+ public static ILogger? Exists(Assembly repositoryAssembly, string name)
{
- if (repositoryAssembly == null)
+ if (repositoryAssembly is null)
{
- throw new ArgumentNullException("repositoryAssembly");
+ throw new ArgumentNullException(nameof(repositoryAssembly));
}
- if (name == null)
+ if (name is null)
{
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
}
return RepositorySelector.GetRepository(repositoryAssembly).Exists(name);
}
@@ -305,9 +281,9 @@
/// </remarks>
public static ILogger[] GetCurrentLoggers(string repository)
{
- if (repository == null)
+ if (repository is null)
{
- throw new ArgumentNullException("repository");
+ throw new ArgumentNullException(nameof(repository));
}
return RepositorySelector.GetRepository(repository).GetCurrentLoggers();
}
@@ -315,7 +291,7 @@
/// <summary>
/// Returns all the currently defined loggers in the specified assembly's repository.
/// </summary>
- /// <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ /// <param name="repositoryAssembly">The assembly to use to look up the repository.</param>
/// <returns>All the defined loggers.</returns>
/// <remarks>
/// <para>
@@ -324,9 +300,9 @@
/// </remarks>
public static ILogger[] GetCurrentLoggers(Assembly repositoryAssembly)
{
- if (repositoryAssembly == null)
+ if (repositoryAssembly is null)
{
- throw new ArgumentNullException("repositoryAssembly");
+ throw new ArgumentNullException(nameof(repositoryAssembly));
}
return RepositorySelector.GetRepository(repositoryAssembly).GetCurrentLoggers();
}
@@ -352,13 +328,13 @@
/// </remarks>
public static ILogger GetLogger(string repository, string name)
{
- if (repository == null)
+ if (repository is null)
{
- throw new ArgumentNullException("repository");
+ throw new ArgumentNullException(nameof(repository));
}
- if (name == null)
+ if (name is null)
{
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
}
return RepositorySelector.GetRepository(repository).GetLogger(name);
}
@@ -366,7 +342,7 @@
/// <summary>
/// Retrieves or creates a named logger.
/// </summary>
- /// <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ /// <param name="repositoryAssembly">The assembly to use to look up the repository.</param>
/// <param name="name">The name of the logger to retrieve.</param>
/// <returns>The logger with the name specified.</returns>
/// <remarks>
@@ -384,13 +360,13 @@
/// </remarks>
public static ILogger GetLogger(Assembly repositoryAssembly, string name)
{
- if (repositoryAssembly == null)
+ if (repositoryAssembly is null)
{
- throw new ArgumentNullException("repositoryAssembly");
+ throw new ArgumentNullException(nameof(repositoryAssembly));
}
- if (name == null)
+ if (name is null)
{
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
}
return RepositorySelector.GetRepository(repositoryAssembly).GetLogger(name);
}
@@ -408,13 +384,17 @@
/// </remarks>
public static ILogger GetLogger(string repository, Type type)
{
- if (repository == null)
+ if (repository is null)
{
- throw new ArgumentNullException("repository");
+ throw new ArgumentNullException(nameof(repository));
}
- if (type == null)
+ if (type is null)
{
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
+ }
+ if (type.FullName is null)
+ {
+ throw new ArgumentException($"Type {type} does not have a full name", nameof(type));
}
return RepositorySelector.GetRepository(repository).GetLogger(type.FullName);
}
@@ -422,7 +402,7 @@
/// <summary>
/// Shorthand for <see cref="M:LogManager.GetLogger(string)"/>.
/// </summary>
- /// <param name="repositoryAssembly">the assembly to use to lookup the repository</param>
+ /// <param name="repositoryAssembly">the assembly to use to look up the repository</param>
/// <param name="type">The <paramref name="type"/> of which the fullname will be used as the name of the logger to retrieve.</param>
/// <returns>The logger with the name specified.</returns>
/// <remarks>
@@ -432,13 +412,17 @@
/// </remarks>
public static ILogger GetLogger(Assembly repositoryAssembly, Type type)
{
- if (repositoryAssembly == null)
+ if (repositoryAssembly is null)
{
- throw new ArgumentNullException("repositoryAssembly");
+ throw new ArgumentNullException(nameof(repositoryAssembly));
}
- if (type == null)
+ if (type is null)
{
- throw new ArgumentNullException("type");
+ throw new ArgumentNullException(nameof(type));
+ }
+ if (type.FullName is null)
+ {
+ throw new ArgumentException($"Type {type} does not have a full name", nameof(type));
}
return RepositorySelector.GetRepository(repositoryAssembly).GetLogger(type.FullName);
}
@@ -458,7 +442,7 @@
/// </para>
/// <para>
/// The <c>shutdown</c> method is careful to close nested
- /// appenders before closing regular appenders. This is allows
+ /// appenders before closing regular appenders. This allows
/// configurations where a regular appender is attached to a logger
/// and again to a nested appender.
/// </para>
@@ -474,7 +458,7 @@
/// <summary>
/// Shuts down the repository for the repository specified.
/// </summary>
- /// <param name="repository">The repository to shutdown.</param>
+ /// <param name="repository">The repository to shut down.</param>
/// <remarks>
/// <para>
/// Calling this method will <b>safely</b> close and remove all
@@ -487,16 +471,16 @@
/// </para>
/// <para>
/// The <c>shutdown</c> method is careful to close nested
- /// appenders before closing regular appenders. This is allows
+ /// appenders before closing regular appenders. This allows
/// configurations where a regular appender is attached to a logger
/// and again to a nested appender.
/// </para>
/// </remarks>
public static void ShutdownRepository(string repository)
{
- if (repository == null)
+ if (repository is null)
{
- throw new ArgumentNullException("repository");
+ throw new ArgumentNullException(nameof(repository));
}
RepositorySelector.GetRepository(repository).Shutdown();
}
@@ -504,7 +488,7 @@
/// <summary>
/// Shuts down the repository for the repository specified.
/// </summary>
- /// <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ /// <param name="repositoryAssembly">The assembly to use to look up the repository.</param>
/// <remarks>
/// <para>
/// Calling this method will <b>safely</b> close and remove all
@@ -518,16 +502,16 @@
/// </para>
/// <para>
/// The <c>shutdown</c> method is careful to close nested
- /// appenders before closing regular appenders. This is allows
+ /// appenders before closing regular appenders. This allows
/// configurations where a regular appender is attached to a logger
/// and again to a nested appender.
/// </para>
/// </remarks>
public static void ShutdownRepository(Assembly repositoryAssembly)
{
- if (repositoryAssembly == null)
+ if (repositoryAssembly is null)
{
- throw new ArgumentNullException("repositoryAssembly");
+ throw new ArgumentNullException(nameof(repositoryAssembly));
}
RepositorySelector.GetRepository(repositoryAssembly).Shutdown();
}
@@ -548,9 +532,9 @@
/// </remarks>
public static void ResetConfiguration(string repository)
{
- if (repository == null)
+ if (repository is null)
{
- throw new ArgumentNullException("repository");
+ throw new ArgumentNullException(nameof(repository));
}
RepositorySelector.GetRepository(repository).ResetConfiguration();
}
@@ -558,7 +542,7 @@
/// <summary>
/// Resets all values contained in this repository instance to their defaults.
/// </summary>
- /// <param name="repositoryAssembly">The assembly to use to lookup the repository to reset.</param>
+ /// <param name="repositoryAssembly">The assembly to use to look up the repository to reset.</param>
/// <remarks>
/// <para>
/// Resets all values contained in the repository instance to their
@@ -571,9 +555,9 @@
/// </remarks>
public static void ResetConfiguration(Assembly repositoryAssembly)
{
- if (repositoryAssembly == null)
+ if (repositoryAssembly is null)
{
- throw new ArgumentNullException("repositoryAssembly");
+ throw new ArgumentNullException(nameof(repositoryAssembly));
}
RepositorySelector.GetRepository(repositoryAssembly).ResetConfiguration();
}
@@ -621,9 +605,9 @@
/// <exception cref="LogException">The specified repository already exists.</exception>
public static ILoggerRepository CreateRepository(string repository)
{
- if (repository == null)
+ if (repository is null)
{
- throw new ArgumentNullException("repository");
+ throw new ArgumentNullException(nameof(repository));
}
return RepositorySelector.CreateRepository(repository, null);
}
@@ -669,13 +653,13 @@
/// <exception cref="LogException">The specified repository already exists.</exception>
public static ILoggerRepository CreateRepository(string repository, Type repositoryType)
{
- if (repository == null)
+ if (repository is null)
{
- throw new ArgumentNullException("repository");
+ throw new ArgumentNullException(nameof(repository));
}
- if (repositoryType == null)
+ if (repositoryType is null)
{
- throw new ArgumentNullException("repositoryType");
+ throw new ArgumentNullException(nameof(repositoryType));
}
return RepositorySelector.CreateRepository(repository, repositoryType);
}
@@ -721,13 +705,13 @@
/// </remarks>
public static ILoggerRepository CreateRepository(Assembly repositoryAssembly, Type repositoryType)
{
- if (repositoryAssembly == null)
+ if (repositoryAssembly is null)
{
- throw new ArgumentNullException("repositoryAssembly");
+ throw new ArgumentNullException(nameof(repositoryAssembly));
}
- if (repositoryType == null)
+ if (repositoryType is null)
{
- throw new ArgumentNullException("repositoryType");
+ throw new ArgumentNullException(nameof(repositoryType));
}
return RepositorySelector.CreateRepository(repositoryAssembly, repositoryType);
}
@@ -769,23 +753,19 @@
/// </remarks>
public static IRepositorySelector RepositorySelector { get; set; }
- #endregion Public Static Methods
-
- #region Private Static Methods
-
/// <summary>
/// Internal method to get pertinent version info.
/// </summary>
/// <returns>A string of version info.</returns>
private static string GetVersionInfo()
{
- System.Text.StringBuilder sb = new System.Text.StringBuilder();
+ var sb = new StringBuilder();
Assembly myAssembly = Assembly.GetExecutingAssembly();
sb.Append("log4net assembly [").Append(myAssembly.FullName).Append("]. ");
sb.Append("Loaded from [").Append(SystemInfo.AssemblyLocationInfo(myAssembly)).Append("]. ");
- sb.Append("(.NET Runtime [").Append(Environment.Version.ToString()).Append("]");
- sb.Append(" on ").Append(Environment.OSVersion.ToString());
+ sb.Append("(.NET Runtime [").Append(Environment.Version).Append("]");
+ sb.Append(" on ").Append(Environment.OSVersion);
sb.Append(")");
return sb.ToString();
}
@@ -826,10 +806,6 @@
Shutdown();
}
- #endregion Private Static Methods
-
- #region Private Static Fields
-
/// <summary>
/// The fully qualified type of the LoggerManager class.
/// </summary>
@@ -838,7 +814,5 @@
/// log message.
/// </remarks>
private static readonly Type declaringType = typeof(LoggerManager);
-
- #endregion Private Static Fields
}
}
\ No newline at end of file
diff --git a/src/log4net/Core/LoggingEvent.cs b/src/log4net/Core/LoggingEvent.cs
index 4498704..908d617 100644
--- a/src/log4net/Core/LoggingEvent.cs
+++ b/src/log4net/Core/LoggingEvent.cs
@@ -1,5 +1,4 @@
#region Apache License
-
//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
@@ -16,34 +15,27 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
-
#endregion
using System;
-using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Runtime.Serialization;
using System.Security;
using System.Security.Principal;
+using System.Threading;
using log4net.Util;
using log4net.Repository;
-using System.ComponentModel;
namespace log4net.Core
{
/// <summary>
/// Portable data structure used by <see cref="LoggingEvent"/>
/// </summary>
- /// <remarks>
- /// <para>
- /// Portable data structure used by <see cref="LoggingEvent"/>
- /// </para>
- /// </remarks>
/// <author>Nicko Cadell</author>
public struct LoggingEventData
{
- #region Public Instance Fields
-
/// <summary>
/// The logger name.
/// </summary>
@@ -52,7 +44,7 @@
/// The logger name.
/// </para>
/// </remarks>
- public string LoggerName;
+ public string? LoggerName;
/// <summary>
/// Level of logging event.
@@ -64,7 +56,7 @@
/// cannot be declared final either.
/// </para>
/// </remarks>
- public Level Level;
+ public Level? Level;
/// <summary>
/// The application supplied message.
@@ -74,7 +66,7 @@
/// The application supplied message of logging event.
/// </para>
/// </remarks>
- public string Message;
+ public string? Message;
/// <summary>
/// The name of thread
@@ -84,7 +76,7 @@
/// The name of thread in which this logging event was generated
/// </para>
/// </remarks>
- public string ThreadName;
+ public string? ThreadName;
/// <summary>
/// Gets or sets the local time the event was logged
@@ -112,9 +104,11 @@
get
{
if (TimeStamp != default && _timeStampUtc == default)
+ {
// TimeStamp field has been set explicitly but TimeStampUtc hasn't
// => use TimeStamp
return TimeStamp.ToUniversalTime();
+ }
return _timeStampUtc;
}
@@ -137,7 +131,7 @@
/// Location information for the caller.
/// </para>
/// </remarks>
- public LocationInfo LocationInfo;
+ public LocationInfo? LocationInfo;
/// <summary>
/// String representation of the user
@@ -148,7 +142,7 @@
/// like DOMAIN\username
/// </para>
/// </remarks>
- public string UserName;
+ public string? UserName;
/// <summary>
/// String representation of the identity.
@@ -158,7 +152,7 @@
/// String representation of the current thread's principal identity.
/// </para>
/// </remarks>
- public string Identity;
+ public string? Identity;
/// <summary>
/// The string representation of the exception
@@ -168,7 +162,7 @@
/// The string representation of the exception
/// </para>
/// </remarks>
- public string ExceptionString;
+ public string? ExceptionString;
/// <summary>
/// String representation of the AppDomain.
@@ -178,7 +172,7 @@
/// String representation of the AppDomain.
/// </para>
/// </remarks>
- public string Domain;
+ public string? Domain;
/// <summary>
/// Additional event specific properties
@@ -190,9 +184,7 @@
/// have a string key and an object value.
/// </para>
/// </remarks>
- public PropertiesDictionary Properties;
-
- #endregion Public Instance Fields
+ public PropertiesDictionary? Properties;
}
/// <summary>
@@ -211,11 +203,11 @@
/// Some of the values in instances of <see cref="LoggingEvent"/>
/// are considered volatile, that is the values are correct at the
/// time the event is delivered to appenders, but will not be consistent
- /// at any time afterwards. If an event is to be stored and then processed
+ /// at any time afterward. If an event is to be stored and then processed
/// at a later time these volatile values must be fixed by calling
/// <see cref="M:FixVolatileData()"/>. There is a performance penalty
/// for incurred by calling <see cref="M:FixVolatileData()"/> but it
- /// is essential to maintaining data consistency.
+ /// is essential to maintain data consistency.
/// </para>
/// </remarks>
/// <author>Nicko Cadell</author>
@@ -227,8 +219,6 @@
{
private static readonly Type declaringType = typeof(LoggingEvent);
- #region Public Instance Constructors
-
/// <summary>
/// Initializes a new instance of the <see cref="LoggingEvent" /> class
/// from the supplied parameters.
@@ -251,17 +241,18 @@
/// to create a logging event.
/// </para>
/// </remarks>
- public LoggingEvent(Type callerStackBoundaryDeclaringType,
- log4net.Repository.ILoggerRepository repository,
+ public LoggingEvent(
+ Type callerStackBoundaryDeclaringType,
+ ILoggerRepository? repository,
string loggerName,
- Level level,
+ Level? level,
object message,
- Exception exception)
+ Exception? exception)
{
m_callerStackBoundaryDeclaringType = callerStackBoundaryDeclaringType;
m_message = message;
- m_repository = repository;
- m_thrownException = exception;
+ Repository = repository;
+ ExceptionObject = exception;
m_data.LoggerName = loggerName;
m_data.Level = level;
@@ -295,13 +286,14 @@
/// will be captured from the environment if requested or fixed.
/// </para>
/// </remarks>
- public LoggingEvent(Type callerStackBoundaryDeclaringType,
- log4net.Repository.ILoggerRepository repository,
+ public LoggingEvent(
+ Type? callerStackBoundaryDeclaringType,
+ ILoggerRepository? repository,
LoggingEventData data,
FixFlags fixedData)
{
m_callerStackBoundaryDeclaringType = callerStackBoundaryDeclaringType;
- m_repository = repository;
+ Repository = repository;
m_data = data;
m_fixFlags = fixedData;
@@ -331,9 +323,11 @@
/// parameter and no other data should be captured from the environment.
/// </para>
/// </remarks>
- public LoggingEvent(Type callerStackBoundaryDeclaringType,
- log4net.Repository.ILoggerRepository repository,
- LoggingEventData data) : this(callerStackBoundaryDeclaringType, repository, data, FixFlags.All)
+ public LoggingEvent(
+ Type? callerStackBoundaryDeclaringType,
+ ILoggerRepository? repository,
+ LoggingEventData data)
+ : this(callerStackBoundaryDeclaringType, repository, data, FixFlags.All)
{
}
@@ -362,10 +356,6 @@
{
}
- #endregion Public Instance Constructors
-
- #region Protected Instance Constructors
-
/// <summary>
/// Serialization constructor
/// </summary>
@@ -403,10 +393,6 @@
m_fixFlags = FixFlags.All;
}
- #endregion Protected Instance Constructors
-
- #region Public Instance Properties
-
/// <summary>
/// Gets the time when the current process started.
/// </summary>
@@ -428,10 +414,7 @@
/// without the process start time being reset.
/// </para>
/// </remarks>
- public static DateTime StartTime
- {
- get { return SystemInfo.ProcessStartTimeUtc.ToLocalTime(); }
- }
+ public static DateTime StartTime => SystemInfo.ProcessStartTimeUtc.ToLocalTime();
/// <summary>
/// Gets the UTC time when the current process started.
@@ -451,10 +434,7 @@
/// without the process start time being reset.
/// </para>
/// </remarks>
- public static DateTime StartTimeUtc
- {
- get { return SystemInfo.ProcessStartTimeUtc; }
- }
+ public static DateTime StartTimeUtc => SystemInfo.ProcessStartTimeUtc;
/// <summary>
/// Gets the <see cref="Level" /> of the logging event.
@@ -467,10 +447,7 @@
/// Gets the <see cref="Level" /> of the logging event.
/// </para>
/// </remarks>
- public Level Level
- {
- get { return m_data.Level; }
- }
+ public Level? Level => m_data.Level;
/// <summary>
/// Gets the time of the logging event.
@@ -483,10 +460,7 @@
/// The TimeStamp is stored in UTC and converted to the local time zone for this computer.
/// </para>
/// </remarks>
- public DateTime TimeStamp
- {
- get { return m_data.TimeStampUtc.ToLocalTime(); }
- }
+ public DateTime TimeStamp => m_data.TimeStampUtc.ToLocalTime();
/// <summary>
/// Gets UTC the time of the logging event.
@@ -494,10 +468,7 @@
/// <value>
/// The UTC time of the logging event.
/// </value>
- public DateTime TimeStampUtc
- {
- get { return m_data.TimeStampUtc; }
- }
+ public DateTime TimeStampUtc => m_data.TimeStampUtc;
/// <summary>
/// Gets the name of the logger that logged the event.
@@ -510,10 +481,7 @@
/// Gets the name of the logger that logged the event.
/// </para>
/// </remarks>
- public string LoggerName
- {
- get { return m_data.LoggerName; }
- }
+ public string? LoggerName => m_data.LoggerName;
/// <summary>
/// Gets the location information for this logging event.
@@ -531,11 +499,11 @@
/// Release builds.
/// </para>
/// </remarks>
- public LocationInfo LocationInformation
+ public LocationInfo? LocationInformation
{
get
{
- if (m_data.LocationInfo == null && this.m_cacheUpdatable)
+ if (m_data.LocationInfo is null && m_cacheUpdatable)
{
m_data.LocationInfo = new LocationInfo(m_callerStackBoundaryDeclaringType);
}
@@ -564,7 +532,7 @@
/// null will be returned.
/// </para>
/// </remarks>
- public object MessageObject
+ public object? MessageObject
{
get { return m_message; }
protected set { m_message = value; }
@@ -590,10 +558,7 @@
/// null will be returned.
/// </para>
/// </remarks>
- public Exception ExceptionObject
- {
- get { return m_thrownException; }
- }
+ public Exception? ExceptionObject { get; }
/// <summary>
/// The <see cref="ILoggerRepository"/> that this event was created in.
@@ -603,20 +568,17 @@
/// The <see cref="ILoggerRepository"/> that this event was created in.
/// </para>
/// </remarks>
- public ILoggerRepository Repository
- {
- get { return m_repository; }
- }
+ public ILoggerRepository? Repository { get; private set; }
/// <summary>
/// Ensure that the repository is set.
/// </summary>
/// <param name="repository">the value for the repository</param>
- internal void EnsureRepository(ILoggerRepository repository)
+ internal void EnsureRepository(ILoggerRepository? repository)
{
- if (repository != null)
+ if (repository is not null)
{
- m_repository = repository;
+ Repository = repository;
}
}
@@ -631,23 +593,23 @@
/// The collected information is cached for future use.
/// </para>
/// </remarks>
- public virtual string RenderedMessage
+ public virtual string? RenderedMessage
{
get
{
- if (m_data.Message == null && this.m_cacheUpdatable)
+ if (m_data.Message is null && m_cacheUpdatable)
{
if (m_message == null)
{
- m_data.Message = "";
+ m_data.Message = string.Empty;
}
- else if (m_message is string)
+ else if (m_message is string s)
{
- m_data.Message = (m_message as string);
+ m_data.Message = s;
}
- else if (m_repository != null)
+ else if (Repository is not null)
{
- m_data.Message = m_repository.RendererMap.FindAndRender(m_message);
+ m_data.Message = Repository.RendererMap.FindAndRender(m_message);
}
else
{
@@ -675,21 +637,21 @@
/// </remarks>
public virtual void WriteRenderedMessage(TextWriter writer)
{
- if (m_data.Message != null)
+ if (m_data.Message is not null)
{
writer.Write(m_data.Message);
}
else
{
- if (m_message != null)
+ if (m_message is not null)
{
- if (m_message is string)
+ if (m_message is string s)
{
- writer.Write(m_message as string);
+ writer.Write(s);
}
- else if (m_repository != null)
+ else if (Repository is not null)
{
- m_repository.RendererMap.FindAndRender(m_message, writer);
+ Repository.RendererMap.FindAndRender(m_message, writer);
}
else
{
@@ -712,16 +674,16 @@
/// The collected information is cached for future use.
/// </para>
/// </remarks>
- public string ThreadName
+ public string? ThreadName
{
get
{
- if (m_data.ThreadName == null && this.m_cacheUpdatable)
+ if (m_data.ThreadName == null && m_cacheUpdatable)
{
// '.NET ThreadPool Worker' appears as a default thread name in the .NET 6-7 thread pool.
// '.NET TP Worker' is the default thread name in the .NET 8+ thread pool.
// Prefer the numeric thread ID instead.
- string threadName = System.Threading.Thread.CurrentThread.Name;
+ string threadName = Thread.CurrentThread.Name;
if (!string.IsNullOrEmpty(threadName) && threadName != ".NET TP Worker" && threadName != ".NET ThreadPool Worker")
{
m_data.ThreadName = threadName;
@@ -733,9 +695,7 @@
// current thread. (Why don't Threads know their own ID?)
try
{
- m_data.ThreadName =
- SystemInfo.CurrentThreadId.ToString(System.Globalization.NumberFormatInfo
- .InvariantInfo);
+ m_data.ThreadName = SystemInfo.CurrentThreadId.ToString(NumberFormatInfo.InvariantInfo);
}
catch (SecurityException)
{
@@ -745,8 +705,7 @@
"Security exception while trying to get current thread ID. Error Ignored. Empty thread name.");
// As a last resort use the hash code of the Thread object
- m_data.ThreadName = System.Threading.Thread.CurrentThread.GetHashCode()
- .ToString(System.Globalization.CultureInfo.InvariantCulture);
+ m_data.ThreadName = Thread.CurrentThread.GetHashCode().ToString(CultureInfo.InvariantCulture);
}
}
}
@@ -805,7 +764,7 @@
public string UserName =>
m_data.UserName ??= TryGetCurrentUserName() ?? SystemInfo.NotAvailableText;
- private string TryGetCurrentUserName()
+ private string? TryGetCurrentUserName()
{
if (_platformDoesNotSupportWindowsIdentity)
{
@@ -840,11 +799,11 @@
}
}
- private string _cachedWindowsIdentityUserName;
+ private string? _cachedWindowsIdentityUserName;
private static string TryReadWindowsIdentityUserName()
{
using var identity = WindowsIdentity.GetCurrent();
- return identity?.Name ?? "";
+ return identity?.Name ?? string.Empty;
}
private static bool _platformDoesNotSupportWindowsIdentity;
@@ -852,52 +811,47 @@
/// <summary>
/// Gets the identity of the current thread principal.
/// </summary>
- /// <value>
- /// The string name of the identity of the current thread principal.
- /// </value>
/// <remarks>
/// <para>
/// Calls <c>System.Threading.Thread.CurrentPrincipal.Identity.Name</c> to get
/// the name of the current thread principal.
/// </para>
/// </remarks>
- public string Identity
+ public string? Identity
{
get
{
- if (m_data.Identity == null && this.m_cacheUpdatable)
+ if (m_data.Identity is null && m_cacheUpdatable)
{
try
{
- if (System.Threading.Thread.CurrentPrincipal != null &&
- System.Threading.Thread.CurrentPrincipal.Identity != null &&
- System.Threading.Thread.CurrentPrincipal.Identity.Name != null)
+ if (Thread.CurrentPrincipal?.Identity?.Name is string name)
{
- m_data.Identity = System.Threading.Thread.CurrentPrincipal.Identity.Name;
+ m_data.Identity = name;
}
else
{
- m_data.Identity = "";
+ m_data.Identity = string.Empty;
}
}
catch (ObjectDisposedException)
{
- // This exception will occur if System.Threading.Thread.CurrentPrincipal.Identity is not null but
+ // This exception will occur if Thread.CurrentPrincipal.Identity is not null but
// the getter of the property Name tries to access disposed objects.
// Seen to happen on IIS 7 or greater with windows authentication.
LogLog.Debug(declaringType,
"Object disposed exception while trying to get current thread principal. Error Ignored. Empty identity name.");
- m_data.Identity = "";
+ m_data.Identity = string.Empty;
}
- catch (System.Security.SecurityException)
+ catch (SecurityException)
{
// This security exception will occur if the caller does not have
// some undefined set of SecurityPermission flags.
LogLog.Debug(declaringType,
"Security exception while trying to get current thread principal. Error Ignored. Empty identity name.");
- m_data.Identity = "";
+ m_data.Identity = string.Empty;
}
}
@@ -908,19 +862,11 @@
/// <summary>
/// Gets the AppDomain friendly name.
/// </summary>
- /// <value>
- /// The AppDomain friendly name.
- /// </value>
- /// <remarks>
- /// <para>
- /// Gets the AppDomain friendly name.
- /// </para>
- /// </remarks>
- public string Domain
+ public string? Domain
{
get
{
- if (m_data.Domain == null && this.m_cacheUpdatable)
+ if (m_data.Domain is null && m_cacheUpdatable)
{
m_data.Domain = SystemInfo.ApplicationFriendlyName;
}
@@ -960,16 +906,12 @@
get
{
// If we have cached properties then return that otherwise changes will be lost
- if (m_data.Properties != null)
+ if (m_data.Properties is not null)
{
return m_data.Properties;
}
- if (m_eventProperties == null)
- {
- m_eventProperties = new PropertiesDictionary();
- }
-
+ m_eventProperties ??= new PropertiesDictionary();
return m_eventProperties;
}
}
@@ -977,9 +919,6 @@
/// <summary>
/// The fixed fields in this event
/// </summary>
- /// <value>
- /// The set of fields that are fixed in this event
- /// </value>
/// <remarks>
/// <para>
/// Fields will not be fixed if they have previously been fixed.
@@ -988,14 +927,10 @@
/// </remarks>
public FixFlags Fix
{
- get { return m_fixFlags; }
- set { this.FixVolatileData(value); }
+ get => m_fixFlags;
+ set => FixVolatileData(value);
}
- #endregion Public Instance Properties
-
- #region Implementation of ISerializable
-
/// <summary>
/// Serializes this object into the <see cref="SerializationInfo" /> provided.
/// </summary>
@@ -1011,7 +946,7 @@
/// is to be used outside that method.
/// </para>
/// </remarks>
- [System.Security.SecurityCritical]
+ [SecurityCritical]
[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand,
SerializationFormatter = true)]
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
@@ -1037,10 +972,6 @@
info.AddValue("Identity", m_data.Identity);
}
- #endregion Implementation of ISerializable
-
- #region Public Instance Methods
-
/// <summary>
/// Gets the portable data for this <see cref="LoggingEvent" />.
/// </summary>
@@ -1090,7 +1021,7 @@
/// </para>
/// </remarks>
[Obsolete("Use GetExceptionString instead")]
- public string GetExceptionStrRep()
+ public string? GetExceptionStrRep()
{
return GetExceptionString();
}
@@ -1108,26 +1039,26 @@
/// <see cref="ILoggerRepository.RendererMap" />.
/// </para>
/// </remarks>
- public string GetExceptionString()
+ public string? GetExceptionString()
{
- if (m_data.ExceptionString == null && this.m_cacheUpdatable)
+ if (m_data.ExceptionString is null && m_cacheUpdatable)
{
- if (m_thrownException != null)
+ if (ExceptionObject is not null)
{
- if (m_repository != null)
+ if (Repository is not null)
{
// Render exception using the repositories renderer map
- m_data.ExceptionString = m_repository.RendererMap.FindAndRender(m_thrownException);
+ m_data.ExceptionString = Repository.RendererMap.FindAndRender(ExceptionObject);
}
else
{
// Very last resort
- m_data.ExceptionString = m_thrownException.ToString();
+ m_data.ExceptionString = ExceptionObject.ToString();
}
}
else
{
- m_data.ExceptionString = "";
+ m_data.ExceptionString = string.Empty;
}
}
@@ -1142,11 +1073,11 @@
/// Some of the values in instances of <see cref="LoggingEvent"/>
/// are considered volatile, that is the values are correct at the
/// time the event is delivered to appenders, but will not be consistent
- /// at any time afterwards. If an event is to be stored and then processed
+ /// at any time afterward. If an event is to be stored and then processed
/// at a later time these volatile values must be fixed by calling
/// <see cref="M:FixVolatileData()"/>. There is a performance penalty
/// incurred by calling <see cref="M:FixVolatileData()"/> but it
- /// is essential to maintaining data consistency.
+ /// is essential to maintain data consistency.
/// </para>
/// <para>
/// Calling <see cref="M:FixVolatileData()"/> is equivalent to
@@ -1173,11 +1104,11 @@
/// Some of the values in instances of <see cref="LoggingEvent"/>
/// are considered volatile, that is the values are correct at the
/// time the event is delivered to appenders, but will not be consistent
- /// at any time afterwards. If an event is to be stored and then processed
+ /// at any time afterward. If an event is to be stored and then processed
/// at a later time these volatile values must be fixed by calling
/// <see cref="M:FixVolatileData()"/>. There is a performance penalty
/// for incurred by calling <see cref="M:FixVolatileData()"/> but it
- /// is essential to maintaining data consistency.
+ /// is essential to maintain data consistency.
/// </para>
/// <para>
/// The <paramref name="fastButLoose"/> param controls the data that
@@ -1218,22 +1149,20 @@
/// </remarks>
protected virtual void FixVolatileData(FixFlags flags)
{
- object forceCreation = null;
-
- //Unlock the cache so that new values can be stored
- //This may not be ideal if we are no longer in the correct context
- //and someone calls fix.
+ // Unlock the cache so that new values can be stored
+ // This may not be ideal if we are no longer in the correct context
+ // and someone calls fix.
m_cacheUpdatable = true;
// determine the flags that we are actually fixing
- var updateFlags = (FixFlags)((flags ^ m_fixFlags) & flags);
+ FixFlags updateFlags = (flags ^ m_fixFlags) & flags;
if (updateFlags > 0)
{
if ((updateFlags & FixFlags.Message) != 0)
{
// Force the message to be rendered
- forceCreation = this.RenderedMessage;
+ _ = RenderedMessage;
m_fixFlags |= FixFlags.Message;
}
@@ -1241,7 +1170,7 @@
if ((updateFlags & FixFlags.ThreadName) != 0)
{
// Grab the thread name
- forceCreation = this.ThreadName;
+ _ = ThreadName;
m_fixFlags |= FixFlags.ThreadName;
}
@@ -1249,7 +1178,7 @@
if ((updateFlags & FixFlags.LocationInfo) != 0)
{
// Force the location information to be loaded
- forceCreation = this.LocationInformation;
+ _ = LocationInformation;
m_fixFlags |= FixFlags.LocationInfo;
}
@@ -1257,7 +1186,7 @@
if ((updateFlags & FixFlags.UserName) != 0)
{
// Grab the user name
- forceCreation = this.UserName;
+ _ = UserName;
m_fixFlags |= FixFlags.UserName;
}
@@ -1265,7 +1194,7 @@
if ((updateFlags & FixFlags.Domain) != 0)
{
// Grab the domain name
- forceCreation = this.Domain;
+ _ = Domain;
m_fixFlags |= FixFlags.Domain;
}
@@ -1273,7 +1202,7 @@
if ((updateFlags & FixFlags.Identity) != 0)
{
// Grab the identity
- forceCreation = this.Identity;
+ _ = Identity;
m_fixFlags |= FixFlags.Identity;
}
@@ -1281,7 +1210,7 @@
if ((updateFlags & FixFlags.Exception) != 0)
{
// Force the exception text to be loaded
- forceCreation = GetExceptionString();
+ _ = GetExceptionString();
m_fixFlags |= FixFlags.Exception;
}
@@ -1294,34 +1223,24 @@
}
}
- // avoid warning CS0219
- if (forceCreation != null)
- {
- }
-
- //Finaly lock everything we've cached.
+ // Finally lock everything we've cached.
m_cacheUpdatable = false;
}
- #endregion Public Instance Methods
-
- #region Protected Instance Methods
-
private void CreateCompositeProperties()
{
var compositeProperties = new CompositeProperties();
- if (m_eventProperties != null)
+ if (m_eventProperties is not null)
{
compositeProperties.Add(m_eventProperties);
}
var logicalThreadProperties = LogicalThreadContext.Properties.GetProperties(false);
- if (logicalThreadProperties != null)
+ if (logicalThreadProperties is not null)
{
compositeProperties.Add(logicalThreadProperties);
}
- var threadProperties = ThreadContext.Properties.GetProperties(false);
- if (threadProperties != null)
+ if (ThreadContext.Properties.GetProperties(false) is PropertiesDictionary threadProperties)
{
compositeProperties.Add(threadProperties);
}
@@ -1353,38 +1272,32 @@
private void CacheProperties()
{
- if (m_data.Properties == null && this.m_cacheUpdatable)
+ if (m_data.Properties is null && m_cacheUpdatable)
{
- if (m_compositeProperties == null)
+ if (m_compositeProperties is null)
{
CreateCompositeProperties();
}
- var flattenedProperties = m_compositeProperties.Flatten();
+ var flattenedProperties = m_compositeProperties!.Flatten();
var fixedProperties = new PropertiesDictionary();
// Validate properties
- foreach (DictionaryEntry entry in flattenedProperties)
+ foreach (KeyValuePair<string, object?> entry in flattenedProperties)
{
- var key = entry.Key as string;
+ object? val = entry.Value;
- if (key != null)
+ // Fix any IFixingRequired objects
+ if (entry.Value is IFixingRequired fixingRequired)
{
- var val = entry.Value;
+ val = fixingRequired.GetFixedObject();
+ }
- // Fix any IFixingRequired objects
- var fixingRequired = val as IFixingRequired;
- if (fixingRequired != null)
- {
- val = fixingRequired.GetFixedObject();
- }
-
- // Strip keys with null values
- if (val != null)
- {
- fixedProperties[key] = val;
- }
+ // Strip keys with null values
+ if (val is not null)
+ {
+ fixedProperties[entry.Key] = val;
}
}
@@ -1393,17 +1306,17 @@
}
/// <summary>
- /// Lookup a composite property in this event
+ /// Looks up a composite property in this event
/// </summary>
/// <param name="key">the key for the property to lookup</param>
/// <returns>the value for the property</returns>
/// <remarks>
/// <para>
- /// This event has composite properties that combine together properties from
+ /// This event has composite properties that combine properties from
/// several different contexts in the following order:
/// <list type="definition">
/// <item>
- /// <term>this events properties</term>
+ /// <term>this event's properties</term>
/// <description>
/// This event has <see cref="Properties"/> that can be set. These
/// properties are specific to this event only.
@@ -1426,19 +1339,19 @@
/// </list>
/// </para>
/// </remarks>
- public object LookupProperty(string key)
+ public object? LookupProperty(string key)
{
- if (m_data.Properties != null)
+ if (m_data.Properties is not null)
{
return m_data.Properties[key];
}
- if (m_compositeProperties == null)
+ if (m_compositeProperties is null)
{
CreateCompositeProperties();
}
- return m_compositeProperties[key];
+ return m_compositeProperties![key];
}
/// <summary>
@@ -1467,13 +1380,9 @@
CreateCompositeProperties();
}
- return m_compositeProperties.Flatten();
+ return m_compositeProperties!.Flatten();
}
- #endregion Public Instance Methods
-
- #region Private Instance Fields
-
/// <summary>
/// The internal logging event data.
/// </summary>
@@ -1482,45 +1391,28 @@
/// <summary>
/// Location information for the caller.
/// </summary>
- public LocationInfo LocationInfo => m_data.LocationInfo;
+ public LocationInfo? LocationInfo => m_data.LocationInfo;
/// <summary>
/// The internal logging event data.
/// </summary>
- private CompositeProperties m_compositeProperties;
+ private CompositeProperties? m_compositeProperties;
/// <summary>
/// The internal logging event data.
/// </summary>
- private PropertiesDictionary m_eventProperties;
+ private PropertiesDictionary? m_eventProperties;
/// <summary>
/// The fully qualified Type of the calling
/// logger class in the stack frame (i.e. the declaring type of the method).
/// </summary>
- private readonly Type m_callerStackBoundaryDeclaringType;
+ private readonly Type? m_callerStackBoundaryDeclaringType;
/// <summary>
/// The application supplied message of logging event.
/// </summary>
- private object m_message;
-
- /// <summary>
- /// The exception that was thrown.
- /// </summary>
- /// <remarks>
- /// This is not serialized. The string representation
- /// is serialized instead.
- /// </remarks>
- private readonly Exception m_thrownException;
-
- /// <summary>
- /// The repository that generated the logging event
- /// </summary>
- /// <remarks>
- /// This is not serialized.
- /// </remarks>
- private ILoggerRepository m_repository = null;
+ private object? m_message;
/// <summary>
/// The fix state for this event
@@ -1535,15 +1427,11 @@
/// Indicated that the internal cache is updateable (ie not fixed)
/// </summary>
/// <remarks>
- /// This is a seperate flag to m_fixFlags as it allows incrementel fixing and simpler
+ /// This is a separate flag to m_fixFlags as it allows incremental fixing and simpler
/// changes in the caching strategy.
/// </remarks>
private bool m_cacheUpdatable = true;
- #endregion Private Instance Fields
-
- #region Constants
-
/// <summary>
/// The key into the Properties map for the host name value.
/// </summary>
@@ -1558,7 +1446,5 @@
/// The key into the Properties map for the user name value.
/// </summary>
public const string UserNameProperty = "log4net:UserName";
-
- #endregion
}
}
\ No newline at end of file
diff --git a/src/log4net/Core/WrapperMap.cs b/src/log4net/Core/WrapperMap.cs
index b2b30e5..16613ac 100644
--- a/src/log4net/Core/WrapperMap.cs
+++ b/src/log4net/Core/WrapperMap.cs
@@ -24,8 +24,6 @@
namespace log4net.Core
{
- #region WrapperCreationHandler
-
/// <summary>
/// Delegate used to handle creation of new wrappers.
/// </summary>
@@ -43,8 +41,6 @@
/// </remarks>
public delegate ILoggerWrapper WrapperCreationHandler(ILogger logger);
- #endregion WrapperCreationHandler
-
/// <summary>
/// Maps between logger objects and wrapper objects.
/// </summary>
@@ -52,7 +48,7 @@
/// <para>
/// This class maintains a mapping between <see cref="ILogger"/> objects and
/// <see cref="ILoggerWrapper"/> objects. Use the <see cref="GetWrapper"/> method to
- /// lookup the <see cref="ILoggerWrapper"/> for the specified <see cref="ILogger"/>.
+ /// look up the <see cref="ILoggerWrapper"/> for the specified <see cref="ILogger"/>.
/// </para>
/// <para>
/// New wrapper instances are created by the <see cref="CreateNewWrapperObject"/>
@@ -66,8 +62,6 @@
/// <author>Gert Driesen</author>
public class WrapperMap
{
- #region Public Instance Constructors
-
/// <summary>
/// Initializes a new instance of the <see cref="WrapperMap" />
/// </summary>
@@ -83,13 +77,9 @@
m_createWrapperHandler = createWrapperHandler;
// Create the delegates for the event callbacks
- m_shutdownHandler = new LoggerRepositoryShutdownEventHandler(ILoggerRepository_Shutdown);
+ m_shutdownHandler = ILoggerRepository_Shutdown;
}
- #endregion Public Instance Constructors
-
- #region Public Instance Properties
-
/// <summary>
/// Gets the wrapper object for the specified logger.
/// </summary>
@@ -99,41 +89,37 @@
/// If the logger is null then the corresponding wrapper is null.
/// </para>
/// <para>
- /// Looks up the wrapper it it has previously been requested and
+ /// Looks up the wrapper it has previously been requested and
/// returns it. If the wrapper has never been requested before then
/// the <see cref="CreateNewWrapperObject"/> virtual method is
/// called.
/// </para>
/// </remarks>
- public virtual ILoggerWrapper GetWrapper(ILogger logger)
+ public virtual ILoggerWrapper? GetWrapper(ILogger? logger)
{
// If the logger is null then the corresponding wrapper is null
- if (logger == null)
+ if (logger is null)
{
return null;
}
lock (this)
{
- // Lookup hierarchy in map.
- Hashtable wrappersMap = (Hashtable)m_repositories[logger.Repository];
-
- if (wrappersMap == null)
+ // Look up hierarchy in map.
+ Hashtable? wrappersMap = (Hashtable?)Repositories[logger.Repository];
+ if (wrappersMap is null)
{
// Hierarchy does not exist in map.
// Must register with hierarchy
-
wrappersMap = new Hashtable();
- m_repositories[logger.Repository] = wrappersMap;
+ Repositories[logger.Repository] = wrappersMap;
// Register for config reset & shutdown on repository
logger.Repository.ShutdownEvent += m_shutdownHandler;
}
// Look for the wrapper object in the map
- ILoggerWrapper wrapperObject = wrappersMap[logger] as ILoggerWrapper;
-
- if (wrapperObject == null)
+ if (wrappersMap[logger] is not ILoggerWrapper wrapperObject)
{
// No wrapper object exists for the specified logger
@@ -148,10 +134,6 @@
}
}
- #endregion Public Instance Properties
-
- #region Protected Instance Properties
-
/// <summary>
/// Gets the map of logger repositories.
/// </summary>
@@ -165,14 +147,7 @@
/// value being the corresponding <see cref="ILoggerWrapper"/>.
/// </para>
/// </remarks>
- protected Hashtable Repositories
- {
- get { return this.m_repositories; }
- }
-
- #endregion Protected Instance Properties
-
- #region Protected Instance Methods
+ protected Hashtable Repositories { get; } = new();
/// <summary>
/// Creates the wrapper object for the specified logger.
@@ -186,13 +161,9 @@
/// can be overridden in a subclass.
/// </para>
/// </remarks>
- protected virtual ILoggerWrapper CreateNewWrapperObject(ILogger logger)
+ protected virtual ILoggerWrapper? CreateNewWrapperObject(ILogger logger)
{
- if (m_createWrapperHandler != null)
- {
- return m_createWrapperHandler(logger);
- }
- return null;
+ return m_createWrapperHandler?.Invoke(logger);
}
/// <summary>
@@ -213,7 +184,7 @@
lock (this)
{
// Remove the repository from map
- m_repositories.Remove(repository);
+ Repositories.Remove(repository);
// Unhook events from the repository
repository.ShutdownEvent -= m_shutdownHandler;
@@ -227,33 +198,21 @@
/// <param name="e">The event args.</param>
private void ILoggerRepository_Shutdown(object sender, EventArgs e)
{
- ILoggerRepository repository = sender as ILoggerRepository;
- if (repository != null)
+ if (sender is ILoggerRepository repository)
{
// Remove all repository from map
RepositoryShutdown(repository);
}
}
- #endregion Protected Instance Methods
-
- #region Private Instance Variables
-
- /// <summary>
- /// Map of logger repositories to hashtables of ILogger to ILoggerWrapper mappings
- /// </summary>
- private readonly Hashtable m_repositories = new Hashtable();
-
/// <summary>
/// The handler to use to create the extension wrapper objects.
/// </summary>
- private readonly WrapperCreationHandler m_createWrapperHandler;
+ private readonly WrapperCreationHandler? m_createWrapperHandler;
/// <summary>
/// Internal reference to the delegate used to register for repository shutdown events.
/// </summary>
private readonly LoggerRepositoryShutdownEventHandler m_shutdownHandler;
-
- #endregion Private Instance Variables
}
}
diff --git a/src/log4net/Filter/NdcFilter.cs b/src/log4net/Filter/NdcFilter.cs
index 4b0a3e0..b7b1c87 100644
--- a/src/log4net/Filter/NdcFilter.cs
+++ b/src/log4net/Filter/NdcFilter.cs
@@ -17,13 +17,6 @@
//
#endregion
-using System;
-using System.Text.RegularExpressions;
-
-using log4net;
-using log4net.Core;
-using log4net.Util;
-
namespace log4net.Filter
{
/// <summary>
@@ -34,7 +27,7 @@
/// Simple filter to match a string in the <see cref="NDC"/>
/// </para>
/// <para>
- /// As the MDC has been replaced with named stacks stored in the
+ /// As the NDC has been replaced with named stacks stored in the
/// properties collections the <see cref="PropertyFilter"/> should
/// be used instead.
/// </para>
@@ -54,7 +47,7 @@
/// </remarks>
public NdcFilter()
{
- base.Key = "NDC";
+ Key = "NDC";
}
}
}
diff --git a/src/log4net/Layout/LayoutSkeleton.cs b/src/log4net/Layout/LayoutSkeleton.cs
index 348eb07..06b959f 100644
--- a/src/log4net/Layout/LayoutSkeleton.cs
+++ b/src/log4net/Layout/LayoutSkeleton.cs
@@ -17,10 +17,8 @@
//
#endregion
-using System;
using System.IO;
-using log4net;
using log4net.Core;
namespace log4net.Layout
@@ -50,42 +48,6 @@
/// <author>Gert Driesen</author>
public abstract class LayoutSkeleton : ILayout, IOptionHandler
{
- #region Member Variables
-
- /// <summary>
- /// The header text
- /// </summary>
- /// <remarks>
- /// <para>
- /// See <see cref="Header"/> for more information.
- /// </para>
- /// </remarks>
- private string m_header = null;
-
- /// <summary>
- /// The footer text
- /// </summary>
- /// <remarks>
- /// <para>
- /// See <see cref="Footer"/> for more information.
- /// </para>
- /// </remarks>
- private string m_footer = null;
-
- /// <summary>
- /// Flag indicating if this layout handles exceptions
- /// </summary>
- /// <remarks>
- /// <para>
- /// <c>false</c> if this layout handles exceptions
- /// </para>
- /// </remarks>
- private bool m_ignoresException = true;
-
- #endregion
-
- #region Constructors
-
/// <summary>
/// Empty default constructor
/// </summary>
@@ -98,10 +60,6 @@
{
}
- #endregion
-
- #region Implementation of IOptionHandler
-
/// <summary>
/// Activate component options
/// </summary>
@@ -123,10 +81,6 @@
/// </remarks>
public abstract void ActivateOptions();
- #endregion
-
- #region Implementation of ILayout
-
/// <summary>
/// Implement this method to create your own layout format.
/// </summary>
@@ -149,7 +103,7 @@
/// </remarks>
public string Format(LoggingEvent loggingEvent)
{
- using StringWriter writer = new StringWriter(System.Globalization.CultureInfo.InvariantCulture);
+ using var writer = new StringWriter(System.Globalization.CultureInfo.InvariantCulture);
Format(writer, loggingEvent);
return writer.ToString();
}
@@ -168,10 +122,7 @@
/// property.
/// </para>
/// </remarks>
- public virtual string ContentType
- {
- get { return "text/plain"; }
- }
+ public virtual string ContentType => "text/plain";
/// <summary>
/// The header for the layout format.
@@ -183,11 +134,7 @@
/// are formatted and appended.
/// </para>
/// </remarks>
- public virtual string Header
- {
- get { return m_header; }
- set { m_header = value; }
- }
+ public virtual string? Header { get; set; }
/// <summary>
/// The footer for the layout format.
@@ -199,11 +146,7 @@
/// have been formatted and appended.
/// </para>
/// </remarks>
- public virtual string Footer
- {
- get { return m_footer; }
- set { m_footer = value; }
- }
+ public virtual string? Footer { get; set; }
/// <summary>
/// Flag indicating if this layout handles exceptions
@@ -217,16 +160,10 @@
/// object, then the layout should return <c>true</c>.
/// </para>
/// <para>
- /// Set this value to override a this default setting. The default
+ /// Set this value to override the default setting. The default
/// value is <c>true</c>, this layout does not handle the exception.
/// </para>
/// </remarks>
- public virtual bool IgnoresException
- {
- get { return m_ignoresException; }
- set { m_ignoresException = value; }
- }
-
- #endregion
+ public virtual bool IgnoresException { get; set; } = true;
}
}
diff --git a/src/log4net/Layout/Pattern/NdcPatternConverter.cs b/src/log4net/Layout/Pattern/NdcPatternConverter.cs
index a64dbb9..cc2293b 100644
--- a/src/log4net/Layout/Pattern/NdcPatternConverter.cs
+++ b/src/log4net/Layout/Pattern/NdcPatternConverter.cs
@@ -17,8 +17,6 @@
//
#endregion
-using System;
-using System.Text;
using System.IO;
using log4net.Core;
diff --git a/src/log4net/Layout/XmlLayout.cs b/src/log4net/Layout/XmlLayout.cs
index c23ecf9..c165074 100644
--- a/src/log4net/Layout/XmlLayout.cs
+++ b/src/log4net/Layout/XmlLayout.cs
@@ -18,6 +18,7 @@
#endregion
using System;
+using System.Collections.Generic;
using System.Text;
using System.Xml;
@@ -72,12 +73,10 @@
/// <author>Gert Driesen</author>
public class XmlLayout : XmlLayoutBase
{
- #region Public Instance Constructors
-
/// <summary>
/// Constructs an XmlLayout
/// </summary>
- public XmlLayout() : base()
+ public XmlLayout()
{
}
@@ -88,7 +87,7 @@
/// <para>
/// The <b>LocationInfo</b> option takes a boolean value. By
/// default, it is set to false which means there will be no location
- /// information output by this layout. If the the option is set to
+ /// information output by this layout. If the option is set to
/// true, then the file name and line number of the statement
/// at the origin of the log statement will be output.
/// </para>
@@ -102,10 +101,6 @@
{
}
- #endregion Public Instance Constructors
-
- #region Public Instance Properties
-
/// <summary>
/// The prefix to use for all element names
/// </summary>
@@ -116,15 +111,10 @@
/// then no prefix will be written.
/// </para>
/// </remarks>
- public string Prefix
- {
- get { return m_prefix; }
- set { m_prefix = value; }
- }
-
-
+ public string Prefix { get; set; } = PREFIX;
+
/// <summary>
- /// Set whether or not to base64 encode the message.
+ /// Set whether to base64 encode the message.
/// </summary>
/// <remarks>
/// <para>
@@ -136,14 +126,10 @@
/// on the log message.
/// </para>
/// </remarks>
- public bool Base64EncodeMessage
- {
- get { return m_base64Message; }
- set { m_base64Message = value; }
- }
+ public bool Base64EncodeMessage { get; set; }
/// <summary>
- /// Set whether or not to base64 encode the property values.
+ /// Set whether to base64 encode the property values.
/// </summary>
/// <remarks>
/// <para>
@@ -155,15 +141,7 @@
/// on the property values.
/// </para>
/// </remarks>
- public bool Base64EncodeProperties
- {
- get { return m_base64Properties; }
- set { m_base64Properties = value; }
- }
-
- #endregion Public Instance Properties
-
- #region Implementation of IOptionHandler
+ public bool Base64EncodeProperties { get; set; }
/// <summary>
/// Initialize layout options
@@ -189,21 +167,17 @@
base.ActivateOptions();
// Cache the full element names including the prefix
- if (m_prefix != null && m_prefix.Length > 0)
+ if (Prefix.Length > 0)
{
- m_elmEvent = m_prefix + ":" + ELM_EVENT;
- m_elmMessage = m_prefix + ":" + ELM_MESSAGE;
- m_elmProperties = m_prefix + ":" + ELM_PROPERTIES;
- m_elmData = m_prefix + ":" + ELM_DATA;
- m_elmException = m_prefix + ":" + ELM_EXCEPTION;
- m_elmLocation = m_prefix + ":" + ELM_LOCATION;
+ m_elmEvent = Prefix + ":" + ELM_EVENT;
+ m_elmMessage = Prefix + ":" + ELM_MESSAGE;
+ m_elmProperties = Prefix + ":" + ELM_PROPERTIES;
+ m_elmData = Prefix + ":" + ELM_DATA;
+ m_elmException = Prefix + ":" + ELM_EXCEPTION;
+ m_elmLocation = Prefix + ":" + ELM_LOCATION;
}
}
- #endregion Implementation of IOptionHandler
-
- #region Override implementation of XMLLayoutBase
-
/// <summary>
/// Does the actual writing of the XML.
/// </summary>
@@ -217,13 +191,13 @@
/// </remarks>
protected override void FormatXml(XmlWriter writer, LoggingEvent loggingEvent)
{
- writer.WriteStartElement(m_elmEvent, m_prefix, ELM_EVENT, m_prefix);
- writer.WriteAttributeString(ATTR_LOGGER, loggingEvent.LoggerName);
+ writer.WriteStartElement(m_elmEvent, Prefix, ELM_EVENT, Prefix);
+ writer.WriteAttributeString(ATTR_LOGGER, loggingEvent.LoggerName!);
writer.WriteAttributeString(ATTR_TIMESTAMP, XmlConvert.ToString(loggingEvent.TimeStamp, XmlDateTimeSerializationMode.Local));
writer.WriteAttributeString(ATTR_LEVEL, loggingEvent.Level.DisplayName);
- writer.WriteAttributeString(ATTR_THREAD, loggingEvent.ThreadName);
+ writer.WriteAttributeString(ATTR_THREAD, loggingEvent.ThreadName!);
if (loggingEvent.Domain != null && loggingEvent.Domain.Length > 0)
{
@@ -233,14 +207,14 @@
{
writer.WriteAttributeString(ATTR_IDENTITY, loggingEvent.Identity);
}
- if (loggingEvent.UserName != null && loggingEvent.UserName.Length > 0)
+ if (loggingEvent.UserName.Length > 0)
{
writer.WriteAttributeString(ATTR_USERNAME, loggingEvent.UserName);
}
// Append the message text
- writer.WriteStartElement(m_elmMessage, m_prefix, ELM_MESSAGE, m_prefix);
- if (!this.Base64EncodeMessage)
+ writer.WriteStartElement(m_elmMessage, Prefix, ELM_MESSAGE, Prefix);
+ if (!Base64EncodeMessage)
{
Transform.WriteEscapedXmlString(writer, loggingEvent.RenderedMessage, this.InvalidCharReplacement);
}
@@ -257,17 +231,17 @@
// Append the properties text
if (properties.Count > 0)
{
- writer.WriteStartElement(m_elmProperties, m_prefix, ELM_PROPERTIES, m_prefix);
- foreach (System.Collections.DictionaryEntry entry in properties)
+ writer.WriteStartElement(m_elmProperties, Prefix, ELM_PROPERTIES, Prefix);
+ foreach (KeyValuePair<string, object?> entry in properties)
{
- writer.WriteStartElement(m_elmData, m_prefix, ELM_DATA, m_prefix);
- writer.WriteAttributeString(ATTR_NAME, Transform.MaskXmlInvalidCharacters((string)entry.Key, this.InvalidCharReplacement));
+ writer.WriteStartElement(m_elmData, Prefix, ELM_DATA, Prefix);
+ writer.WriteAttributeString(ATTR_NAME, Transform.MaskXmlInvalidCharacters(entry.Key, InvalidCharReplacement));
// Use an ObjectRenderer to convert the object to a string
- string valueStr = null;
- if (!this.Base64EncodeProperties)
+ string valueStr;
+ if (!Base64EncodeProperties)
{
- valueStr = Transform.MaskXmlInvalidCharacters(loggingEvent.Repository.RendererMap.FindAndRender(entry.Value), this.InvalidCharReplacement);
+ valueStr = Transform.MaskXmlInvalidCharacters(loggingEvent.Repository.RendererMap.FindAndRender(entry.Value), InvalidCharReplacement);
}
else
{
@@ -285,8 +259,8 @@
if (exceptionStr != null && exceptionStr.Length > 0)
{
// Append the stack trace line
- writer.WriteStartElement(m_elmException, m_prefix, ELM_EXCEPTION, m_prefix);
- Transform.WriteEscapedXmlString(writer, exceptionStr, this.InvalidCharReplacement);
+ writer.WriteStartElement(m_elmException, Prefix, ELM_EXCEPTION, Prefix);
+ Transform.WriteEscapedXmlString(writer, exceptionStr, InvalidCharReplacement);
writer.WriteEndElement();
}
@@ -294,7 +268,7 @@
{
LocationInfo locationInfo = loggingEvent.LocationInformation;
- writer.WriteStartElement(m_elmLocation, m_prefix, ELM_LOCATION, m_prefix);
+ writer.WriteStartElement(m_elmLocation, Prefix, ELM_LOCATION, Prefix);
writer.WriteAttributeString(ATTR_CLASS, locationInfo.ClassName);
writer.WriteAttributeString(ATTR_METHOD, locationInfo.MethodName);
writer.WriteAttributeString(ATTR_FILE, locationInfo.FileName);
@@ -305,15 +279,6 @@
writer.WriteEndElement();
}
- #endregion Override implementation of XMLLayoutBase
-
- #region Private Instance Fields
-
- /// <summary>
- /// The prefix to use for all generated element names
- /// </summary>
- private string m_prefix = PREFIX;
-
private string m_elmEvent = ELM_EVENT;
private string m_elmMessage = ELM_MESSAGE;
private string m_elmData = ELM_DATA;
@@ -321,19 +286,11 @@
private string m_elmException = ELM_EXCEPTION;
private string m_elmLocation = ELM_LOCATION;
- private bool m_base64Message = false;
- private bool m_base64Properties = false;
-
- #endregion Private Instance Fields
-
- #region Private Static Fields
-
private const string PREFIX = "log4net";
private const string ELM_EVENT = "event";
private const string ELM_MESSAGE = "message";
private const string ELM_PROPERTIES = "properties";
- private const string ELM_GLOBAL_PROPERTIES = "global-properties";
private const string ELM_DATA = "data";
private const string ELM_EXCEPTION = "exception";
private const string ELM_LOCATION = "locationInfo";
@@ -351,9 +308,6 @@
private const string ATTR_LINE = "line";
private const string ATTR_NAME = "name";
private const string ATTR_VALUE = "value";
-
-
- #endregion Private Static Fields
}
}
diff --git a/src/log4net/Layout/XmlLayoutBase.cs b/src/log4net/Layout/XmlLayoutBase.cs
index 798fcc6..0002c46 100644
--- a/src/log4net/Layout/XmlLayoutBase.cs
+++ b/src/log4net/Layout/XmlLayoutBase.cs
@@ -19,7 +19,6 @@
using System;
using System.IO;
-using System.Text;
using System.Xml;
using log4net.Util;
@@ -44,8 +43,6 @@
/// <author>Gert Driesen</author>
public abstract class XmlLayoutBase : LayoutSkeleton
{
- #region Protected Instance Constructors
-
/// <summary>
/// Protected constructor to support subclasses
/// </summary>
@@ -80,13 +77,9 @@
protected XmlLayoutBase(bool locationInfo)
{
IgnoresException = false;
- m_locationInfo = locationInfo;
+ LocationInfo = locationInfo;
}
- #endregion Protected Instance Constructors
-
- #region Public Instance Properties
-
/// <summary>
/// Gets a value indicating whether to include location information in
/// the XML events.
@@ -107,11 +100,8 @@
/// appender as well.
/// </para>
/// </remarks>
- public bool LocationInfo
- {
- get { return m_locationInfo; }
- set { m_locationInfo = value; }
- }
+ public bool LocationInfo { get; set; }
+
/// <summary>
/// The string to replace characters that can not be expressed in XML with.
/// <remarks>
@@ -125,14 +115,7 @@
/// </para>
/// </remarks>
/// </summary>
- public string InvalidCharReplacement
- {
- get { return m_invalidCharReplacement; }
- set { m_invalidCharReplacement = value; }
- }
- #endregion
-
- #region Implementation of IOptionHandler
+ public string InvalidCharReplacement { get; set; } = "?";
/// <summary>
/// Initialize layout options
@@ -155,10 +138,6 @@
// nothing to do
}
- #endregion Implementation of IOptionHandler
-
- #region Override implementation of LayoutSkeleton
-
/// <summary>
/// Gets the content type output by this layout.
/// </summary>
@@ -193,9 +172,9 @@
/// </remarks>
public override void Format(TextWriter writer, LoggingEvent loggingEvent)
{
- if (loggingEvent == null)
+ if (loggingEvent is null)
{
- throw new ArgumentNullException("loggingEvent");
+ throw new ArgumentNullException(nameof(loggingEvent));
}
using XmlWriter xmlWriter = XmlWriterExtensions.CreateXmlWriter(writer);
// Write the event to the writer
@@ -208,10 +187,6 @@
// -> Dispose from using var will close & flush
}
- #endregion Override implementation of LayoutSkeleton
-
- #region Protected Instance Methods
-
/// <summary>
/// Does the actual writing of the XML.
/// </summary>
@@ -224,22 +199,5 @@
/// </para>
/// </remarks>
protected abstract void FormatXml(XmlWriter writer, LoggingEvent loggingEvent);
-
- #endregion Protected Instance Methods
-
- #region Private Instance Fields
-
- /// <summary>
- /// Flag to indicate if location information should be included in
- /// the XML events.
- /// </summary>
- private bool m_locationInfo = false;
-
- /// <summary>
- /// The string to replace invalid chars with
- /// </summary>
- private string m_invalidCharReplacement = "?";
-
- #endregion Private Instance Fields
}
}
\ No newline at end of file
diff --git a/src/log4net/Layout/XmlLayoutSchemaLog4j.cs b/src/log4net/Layout/XmlLayoutSchemaLog4j.cs
index ef69e23..734a164 100644
--- a/src/log4net/Layout/XmlLayoutSchemaLog4j.cs
+++ b/src/log4net/Layout/XmlLayoutSchemaLog4j.cs
@@ -18,9 +18,8 @@
#endregion
using System;
-using System.Text;
+using System.Collections.Generic;
using System.Xml;
-using System.IO;
using log4net.Core;
using log4net.Util;
@@ -39,21 +38,15 @@
/// <author>Nicko Cadell</author>
public class XmlLayoutSchemaLog4j : XmlLayoutBase
{
- #region Static Members
-
/// <summary>
/// The 1st of January 1970 in UTC
/// </summary>
- private static readonly DateTime s_date1970 = new DateTime(1970, 1, 1);
-
- #endregion
-
- #region Constructors
+ private static readonly DateTime s_date1970 = new(1970, 1, 1);
/// <summary>
/// Constructs an XMLLayoutSchemaLog4j
/// </summary>
- public XmlLayoutSchemaLog4j() : base()
+ public XmlLayoutSchemaLog4j()
{
}
@@ -64,7 +57,7 @@
/// <para>
/// The <b>LocationInfo</b> option takes a boolean value. By
/// default, it is set to false which means there will be no location
- /// information output by this layout. If the the option is set to
+ /// information output by this layout. If the option is set to
/// true, then the file name and line number of the statement
/// at the origin of the log statement will be output.
/// </para>
@@ -78,10 +71,6 @@
{
}
- #endregion
-
- #region Public Properties
-
/// <summary>
/// The version of the log4j schema to use.
/// </summary>
@@ -102,8 +91,6 @@
}
}
- #endregion
-
/* Example log4j schema event
<log4j:event logger="first logger" level="ERROR" thread="Thread-3" timestamp="1051494121460">
@@ -142,32 +129,31 @@
// Translate logging events for log4j
// Translate hostname property
- if (loggingEvent.LookupProperty(LoggingEvent.HostNameProperty) != null &&
- loggingEvent.LookupProperty("log4jmachinename") == null)
+ if (loggingEvent.LookupProperty(LoggingEvent.HostNameProperty) is not null &&
+ loggingEvent.LookupProperty("log4jmachinename") is null)
{
loggingEvent.GetProperties()["log4jmachinename"] = loggingEvent.LookupProperty(LoggingEvent.HostNameProperty);
}
// translate appdomain name
- if (loggingEvent.LookupProperty("log4japp") == null &&
- loggingEvent.Domain != null &&
+ if (loggingEvent.LookupProperty("log4japp") is null &&
+ loggingEvent.Domain is not null &&
loggingEvent.Domain.Length > 0)
{
loggingEvent.GetProperties()["log4japp"] = loggingEvent.Domain;
}
// translate identity name
- if (loggingEvent.Identity != null &&
+ if (loggingEvent.Identity is not null &&
loggingEvent.Identity.Length > 0 &&
- loggingEvent.LookupProperty(LoggingEvent.IdentityProperty) == null)
+ loggingEvent.LookupProperty(LoggingEvent.IdentityProperty) is null)
{
loggingEvent.GetProperties()[LoggingEvent.IdentityProperty] = loggingEvent.Identity;
}
// translate user name
- if (loggingEvent.UserName != null &&
- loggingEvent.UserName.Length > 0 &&
- loggingEvent.LookupProperty(LoggingEvent.UserNameProperty) == null)
+ if (loggingEvent.UserName.Length > 0 &&
+ loggingEvent.LookupProperty(LoggingEvent.UserNameProperty) is null)
{
loggingEvent.GetProperties()[LoggingEvent.UserNameProperty] = loggingEvent.UserName;
}
@@ -189,19 +175,19 @@
// Append the message text
writer.WriteStartElement("log4j:message", "log4j", "message", "log4net");
- Transform.WriteEscapedXmlString(writer, loggingEvent.RenderedMessage, this.InvalidCharReplacement);
+ Transform.WriteEscapedXmlString(writer, loggingEvent.RenderedMessage, InvalidCharReplacement);
writer.WriteEndElement();
object ndcObj = loggingEvent.LookupProperty("NDC");
- if (ndcObj != null)
+ if (ndcObj is not null)
{
- string valueStr = loggingEvent.Repository.RendererMap.FindAndRender(ndcObj);
+ string? valueStr = loggingEvent.Repository.RendererMap.FindAndRender(ndcObj);
- if (valueStr != null && valueStr.Length > 0)
+ if (valueStr is not null && valueStr.Length > 0)
{
// Append the NDC text
writer.WriteStartElement("log4j:NDC", "log4j", "NDC", "log4net");
- Transform.WriteEscapedXmlString(writer, valueStr, this.InvalidCharReplacement);
+ Transform.WriteEscapedXmlString(writer, valueStr, InvalidCharReplacement);
writer.WriteEndElement();
}
}
@@ -211,10 +197,10 @@
if (properties.Count > 0)
{
writer.WriteStartElement("log4j:properties", "log4j", "properties", "log4net");
- foreach (System.Collections.DictionaryEntry entry in properties)
+ foreach (KeyValuePair<string, object?> entry in properties)
{
writer.WriteStartElement("log4j:data", "log4j", "data", "log4net");
- writer.WriteAttributeString("name", (string)entry.Key);
+ writer.WriteAttributeString("name", entry.Key);
// Use an ObjectRenderer to convert the object to a string
string valueStr = loggingEvent.Repository.RendererMap.FindAndRender(entry.Value);
@@ -230,13 +216,13 @@
{
// Append the stack trace line
writer.WriteStartElement("log4j:throwable", "log4j", "data", "log4net");
- Transform.WriteEscapedXmlString(writer, exceptionStr, this.InvalidCharReplacement);
+ Transform.WriteEscapedXmlString(writer, exceptionStr, InvalidCharReplacement);
writer.WriteEndElement();
}
if (LocationInfo)
{
- LocationInfo locationInfo = loggingEvent.LocationInformation;
+ LocationInfo? locationInfo = loggingEvent.LocationInformation;
writer.WriteStartElement("log4j:locationInfo", "log4j", "locationInfo", "log4net");
writer.WriteAttributeString("class", locationInfo.ClassName);
diff --git a/src/log4net/LogManager.cs b/src/log4net/LogManager.cs
index 939295e..c78b7f0 100644
--- a/src/log4net/LogManager.cs
+++ b/src/log4net/LogManager.cs
@@ -19,7 +19,7 @@
using System;
using System.Reflection;
-
+using log4net.Appender;
using log4net.Core;
using log4net.Repository;
@@ -55,24 +55,8 @@
/// <seealso cref="ILog"/>
/// <author>Nicko Cadell</author>
/// <author>Gert Driesen</author>
- public sealed class LogManager
+ public static class LogManager
{
- #region Private Instance Constructors
-
- /// <summary>
- /// Initializes a new instance of the <see cref="LogManager" /> class.
- /// </summary>
- /// <remarks>
- /// Uses a private access modifier to prevent instantiation of this class.
- /// </remarks>
- private LogManager()
- {
- }
-
- #endregion Private Instance Constructors
-
- #region Type Specific Manager Methods
-
/// <overloads>Returns the named logger if it exists.</overloads>
/// <summary>
/// Returns the named logger if it exists.
@@ -85,7 +69,7 @@
/// </remarks>
/// <param name="name">The fully qualified logger name to look for.</param>
/// <returns>The logger found, or <c>null</c> if no logger could be found.</returns>
- public static ILog Exists(string name)
+ public static ILog? Exists(string name)
{
return Exists(Assembly.GetCallingAssembly(), name);
}
@@ -142,7 +126,7 @@
/// The logger found, or <c>null</c> if the logger doesn't exist in the specified
/// repository.
/// </returns>
- public static ILog Exists(string repository, string name)
+ public static ILog? Exists(string repository, string name)
{
return WrapLogger(LoggerManager.Exists(repository, name));
}
@@ -157,13 +141,13 @@
/// <c>null</c>.
/// </para>
/// </remarks>
- /// <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ /// <param name="repositoryAssembly">The assembly to use to look up the repository.</param>
/// <param name="name">The fully qualified logger name to look for.</param>
/// <returns>
/// The logger, or <c>null</c> if the logger doesn't exist in the specified
/// assembly's repository.
/// </returns>
- public static ILog Exists(Assembly repositoryAssembly, string name)
+ public static ILog? Exists(Assembly repositoryAssembly, string name)
{
return WrapLogger(LoggerManager.Exists(repositoryAssembly, name));
}
@@ -184,7 +168,7 @@
/// <summary>
/// Returns all the currently defined loggers in the specified assembly's repository.
/// </summary>
- /// <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ /// <param name="repositoryAssembly">The assembly to use to look up the repository.</param>
/// <remarks>
/// The root logger is <b>not</b> included in the returned array.
/// </remarks>
@@ -215,7 +199,7 @@
/// <returns>The logger with the name specified.</returns>
public static ILog GetLogger(string repository, string name)
{
- return WrapLogger(LoggerManager.GetLogger(repository, name));
+ return WrapLogger(LoggerManager.GetLogger(repository, name))!;
}
/// <summary>
@@ -234,12 +218,12 @@
/// log4net.
/// </para>
/// </remarks>
- /// <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ /// <param name="repositoryAssembly">The assembly to use to look up the repository.</param>
/// <param name="name">The name of the logger to retrieve.</param>
/// <returns>The logger with the name specified.</returns>
public static ILog GetLogger(Assembly repositoryAssembly, string name)
{
- return WrapLogger(LoggerManager.GetLogger(repositoryAssembly, name));
+ return WrapLogger(LoggerManager.GetLogger(repositoryAssembly, name))!;
}
/// <summary>
@@ -252,7 +236,7 @@
/// <returns>The logger with the name specified.</returns>
public static ILog GetLogger(Type type)
{
- return GetLogger(Assembly.GetCallingAssembly(), type.FullName);
+ return GetLogger(Assembly.GetCallingAssembly(), type.FullName!);
}
/// <summary>
@@ -266,7 +250,7 @@
/// <returns>The logger with the name specified.</returns>
public static ILog GetLogger(string repository, Type type)
{
- return WrapLogger(LoggerManager.GetLogger(repository, type));
+ return WrapLogger(LoggerManager.GetLogger(repository, type))!;
}
/// <summary>
@@ -275,18 +259,14 @@
/// <remarks>
/// Gets the logger for the fully qualified name of the type specified.
/// </remarks>
- /// <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ /// <param name="repositoryAssembly">The assembly to use to look up the repository.</param>
/// <param name="type">The full name of <paramref name="type"/> will be used as the name of the logger to retrieve.</param>
/// <returns>The logger with the name specified.</returns>
public static ILog GetLogger(Assembly repositoryAssembly, Type type)
{
- return WrapLogger(LoggerManager.GetLogger(repositoryAssembly, type));
+ return WrapLogger(LoggerManager.GetLogger(repositoryAssembly, type))!;
}
- #endregion Type Specific Manager Methods
-
- #region Domain & Repository Manager Methods
-
/// <summary>
/// Shuts down the log4net system.
/// </summary>
@@ -301,7 +281,7 @@
/// Otherwise, pending logging events might be lost.
/// </para>
/// <para>The <c>shutdown</c> method is careful to close nested
- /// appenders before closing regular appenders. This is allows
+ /// appenders before closing regular appenders. This allows
/// configurations where a regular appender is attached to a logger
/// and again to a nested appender.
/// </para>
@@ -325,7 +305,7 @@
/// Otherwise, pending logging events might be lost.
/// </para>
/// <para>The <c>shutdown</c> method is careful to close nested
- /// appenders before closing regular appenders. This is allows
+ /// appenders before closing regular appenders. This allows
/// configurations where a regular appender is attached to a logger
/// and again to a nested appender.
/// </para>
@@ -349,12 +329,12 @@
/// Otherwise, pending logging events might be lost.
/// </para>
/// <para>The <c>shutdown</c> method is careful to close nested
- /// appenders before closing regular appenders. This is allows
+ /// appenders before closing regular appenders. This allows
/// configurations where a regular appender is attached to a logger
/// and again to a nested appender.
/// </para>
/// </remarks>
- /// <param name="repository">The repository to shutdown.</param>
+ /// <param name="repository">The repository to shut down.</param>
public static void ShutdownRepository(string repository)
{
LoggerManager.ShutdownRepository(repository);
@@ -376,12 +356,12 @@
/// </para>
/// <para>
/// The <c>shutdown</c> method is careful to close nested
- /// appenders before closing regular appenders. This is allows
+ /// appenders before closing regular appenders. This allows
/// configurations where a regular appender is attached to a logger
/// and again to a nested appender.
/// </para>
/// </remarks>
- /// <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ /// <param name="repositoryAssembly">The assembly to use to look up the repository.</param>
public static void ShutdownRepository(Assembly repositoryAssembly)
{
LoggerManager.ShutdownRepository(repositoryAssembly);
@@ -438,7 +418,7 @@
/// message disabling is set to its default "off" value.
/// </para>
/// </remarks>
- /// <param name="repositoryAssembly">The assembly to use to lookup the repository to reset.</param>
+ /// <param name="repositoryAssembly">The assembly to use to look up the repository to reset.</param>
public static void ResetConfiguration(Assembly repositoryAssembly)
{
LoggerManager.ResetConfiguration(repositoryAssembly);
@@ -488,7 +468,7 @@
/// by the <paramref name="repositoryAssembly"/> argument.
/// </para>
/// </remarks>
- /// <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ /// <param name="repositoryAssembly">The assembly to use to look up the repository.</param>
[Obsolete("Use GetRepository instead of GetLoggerRepository")]
public static ILoggerRepository GetLoggerRepository(Assembly repositoryAssembly)
{
@@ -537,7 +517,7 @@
/// by the <paramref name="repositoryAssembly"/> argument.
/// </para>
/// </remarks>
- /// <param name="repositoryAssembly">The assembly to use to lookup the repository.</param>
+ /// <param name="repositoryAssembly">The assembly to use to look up the repository.</param>
public static ILoggerRepository GetRepository(Assembly repositoryAssembly)
{
return LoggerManager.GetRepository(repositoryAssembly);
@@ -738,33 +718,26 @@
/// <summary>
/// Flushes logging events buffered in all configured appenders in the default repository.
/// </summary>
- /// <param name="millisecondsTimeout">The maximum time in milliseconds to wait for logging events from asycnhronous appenders to be flushed.</param>
+ /// <param name="millisecondsTimeout">The maximum time in milliseconds to wait for logging events from asynchronous appenders to be flushed.</param>
/// <returns><c>True</c> if all logging events were flushed successfully, else <c>false</c>.</returns>
public static bool Flush(int millisecondsTimeout)
{
- Appender.IFlushable flushableRepository = LoggerManager.GetRepository(Assembly.GetCallingAssembly()) as Appender.IFlushable;
- if (flushableRepository == null)
+ if (LoggerManager.GetRepository(Assembly.GetCallingAssembly()) is not IFlushable flushableRepository)
{
return false;
}
- else
- {
- return flushableRepository.Flush(millisecondsTimeout);
- }
+
+ return flushableRepository.Flush(millisecondsTimeout);
}
- #endregion Domain & Repository Manager Methods
-
- #region Extension Handlers
-
/// <summary>
/// Looks up the wrapper object for the logger specified.
/// </summary>
/// <param name="logger">The logger to get the wrapper for.</param>
/// <returns>The wrapper for the logger specified.</returns>
- private static ILog WrapLogger(ILogger logger)
+ private static ILog? WrapLogger(ILogger? logger)
{
- return (ILog)s_wrapperMap.GetWrapper(logger);
+ return (ILog?)s_wrapperMap.GetWrapper(logger);
}
/// <summary>
@@ -793,15 +766,9 @@
return new LogImpl(logger);
}
- #endregion
-
- #region Private Static Fields
-
/// <summary>
/// The wrapper map to use to hold the <see cref="LogImpl"/> objects.
/// </summary>
- private static readonly WrapperMap s_wrapperMap = new WrapperMap(new WrapperCreationHandler(WrapperCreationHandler));
-
- #endregion Private Static Fields
+ private static readonly WrapperMap s_wrapperMap = new(WrapperCreationHandler);
}
}
\ No newline at end of file
diff --git a/src/log4net/LogicalThreadContext.cs b/src/log4net/LogicalThreadContext.cs
index ca399f6..f19e230 100644
--- a/src/log4net/LogicalThreadContext.cs
+++ b/src/log4net/LogicalThreadContext.cs
@@ -82,73 +82,22 @@
/// </example>
/// <threadsafety static="true" instance="true" />
/// <author>Nicko Cadell</author>
- public sealed class LogicalThreadContext
+ public static class LogicalThreadContext
{
- #region Private Instance Constructors
-
- /// <summary>
- /// Private Constructor.
- /// </summary>
- /// <remarks>
- /// <para>
- /// Uses a private access modifier to prevent instantiation of this class.
- /// </para>
- /// </remarks>
- private LogicalThreadContext()
- {
- }
-
- #endregion Private Instance Constructors
-
- #region Public Static Properties
-
/// <summary>
/// The thread properties map
/// </summary>
- /// <value>
- /// The thread properties map
- /// </value>
/// <remarks>
/// <para>
/// The <c>LogicalThreadContext</c> properties override any <see cref="ThreadContext"/>
/// or <see cref="GlobalContext"/> properties with the same name.
/// </para>
/// </remarks>
- public static LogicalThreadContextProperties Properties
- {
- get { return s_properties; }
- }
+ public static LogicalThreadContextProperties Properties { get; } = new();
/// <summary>
- /// The thread stacks
- /// </summary>
- /// <value>
- /// stack map
- /// </value>
- /// <remarks>
- /// <para>
/// The logical thread stacks.
- /// </para>
- /// </remarks>
- public static LogicalThreadContextStacks Stacks
- {
- get { return s_stacks; }
- }
-
- #endregion Public Static Properties
-
- #region Private Static Fields
-
- /// <summary>
- /// The thread context properties instance
/// </summary>
- private static readonly LogicalThreadContextProperties s_properties = new LogicalThreadContextProperties();
-
- /// <summary>
- /// The thread context stacks instance
- /// </summary>
- private static readonly LogicalThreadContextStacks s_stacks = new LogicalThreadContextStacks(s_properties);
-
- #endregion Private Static Fields
+ public static LogicalThreadContextStacks Stacks { get; } = new(Properties);
}
}
\ No newline at end of file
diff --git a/src/log4net/NDC.cs b/src/log4net/NDC.cs
index 9109cc6..ea939c9 100644
--- a/src/log4net/NDC.cs
+++ b/src/log4net/NDC.cs
@@ -44,7 +44,7 @@
/// come into play.
/// </para>
/// <para>
- /// Note that NDCs are managed on a per thread basis. The NDC class
+ /// Note that NDCs are managed on a per-thread basis. The NDC class
/// is made up of static methods that operate on the context of the
/// calling thread.
/// </para>
@@ -62,24 +62,8 @@
/// <author>Nicko Cadell</author>
/// <author>Gert Driesen</author>
/*[Obsolete("NDC has been replaced by ThreadContext.Stacks")]*/
- public sealed class NDC
+ public static class NDC
{
- #region Private Instance Constructors
-
- /// <summary>
- /// Initializes a new instance of the <see cref="NDC" /> class.
- /// </summary>
- /// <remarks>
- /// Uses a private access modifier to prevent instantiation of this class.
- /// </remarks>
- private NDC()
- {
- }
-
- #endregion Private Instance Constructors
-
- #region Public Static Properties
-
/// <summary>
/// Gets the current context depth.
/// </summary>
@@ -106,10 +90,6 @@
get { return ThreadContext.Stacks["NDC"].Count; }
}
- #endregion Public Static Properties
-
- #region Public Static Methods
-
/// <summary>
/// Clears all the contextual information held on the current thread.
/// </summary>
@@ -201,7 +181,7 @@
/// </para>
/// </remarks>
/*[Obsolete("NDC has been replaced by ThreadContext.Stacks")]*/
- public static string Pop()
+ public static string? Pop()
{
return ThreadContext.Stacks["NDC"].Pop();
}
@@ -324,7 +304,7 @@
{
if (maxDepth >= 0)
{
- log4net.Util.ThreadContextStack stack = ThreadContext.Stacks["NDC"];
+ Util.ThreadContextStack stack = ThreadContext.Stacks["NDC"];
if (maxDepth == 0)
{
@@ -339,7 +319,5 @@
}
}
}
-
- #endregion Public Static Methods
}
-}
\ No newline at end of file
+}
diff --git a/src/log4net/Repository/Hierarchy/DefaultLoggerFactory.cs b/src/log4net/Repository/Hierarchy/DefaultLoggerFactory.cs
index 2f55243..3aea766 100644
--- a/src/log4net/Repository/Hierarchy/DefaultLoggerFactory.cs
+++ b/src/log4net/Repository/Hierarchy/DefaultLoggerFactory.cs
@@ -35,55 +35,27 @@
/// <author>Gert Driesen</author>
internal class DefaultLoggerFactory : ILoggerFactory
{
- #region Internal Instance Constructors
-
/// <summary>
- /// Default constructor
- /// </summary>
- /// <remarks>
- /// <para>
- /// Initializes a new instance of the <see cref="DefaultLoggerFactory" /> class.
- /// </para>
- /// </remarks>
- internal DefaultLoggerFactory()
- {
- }
-
- #endregion Internal Instance Constructors
-
- #region Implementation of ILoggerFactory
-
- /// <summary>
- /// Create a new <see cref="Logger" /> instance
+ /// Create a new <see cref="Logger" /> instance with the specified name.
/// </summary>
/// <param name="repository">The <see cref="ILoggerRepository" /> that will own the <see cref="Logger" />.</param>
- /// <param name="name">The name of the <see cref="Logger" />.</param>
+ /// <param name="name">The name of the <see cref="Logger" />. If <c>null</c>, the root logger is returned.</param>
/// <returns>The <see cref="Logger" /> instance for the specified name.</returns>
/// <remarks>
/// <para>
- /// Create a new <see cref="Logger" /> instance with the
- /// specified name.
- /// </para>
- /// <para>
/// Called by the <see cref="Hierarchy"/> to create
/// new named <see cref="Logger"/> instances.
/// </para>
- /// <para>
- /// If the <paramref name="name"/> is <c>null</c> then the root logger
- /// must be returned.
- /// </para>
/// </remarks>
- public Logger CreateLogger(ILoggerRepository repository, string name)
+ public Logger CreateLogger(ILoggerRepository repository, string? name)
{
- if (name == null)
+ if (name is null)
{
return new RootLogger(repository.LevelMap.LookupWithDefault(Level.Debug));
}
return new LoggerImpl(name);
}
- #endregion
-
/// <summary>
/// Default internal subclass of <see cref="Logger"/>
/// </summary>
@@ -97,15 +69,10 @@
internal sealed class LoggerImpl : Logger
{
/// <summary>
- /// Construct a new Logger
- /// </summary>
- /// <param name="name">the name of the logger</param>
- /// <remarks>
- /// <para>
/// Initializes a new instance of the <see cref="LoggerImpl" /> class
/// with the specified name.
- /// </para>
- /// </remarks>
+ /// </summary>
+ /// <param name="name">the name of the logger</param>
internal LoggerImpl(string name) : base(name)
{
}
diff --git a/src/log4net/Repository/Hierarchy/Hierarchy.cs b/src/log4net/Repository/Hierarchy/Hierarchy.cs
index 144b5c4..56dd296 100644
--- a/src/log4net/Repository/Hierarchy/Hierarchy.cs
+++ b/src/log4net/Repository/Hierarchy/Hierarchy.cs
@@ -18,16 +18,15 @@
#endregion
using System;
-using System.Collections;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
using log4net.Appender;
using log4net.Core;
-using log4net.Repository;
using log4net.Util;
namespace log4net.Repository.Hierarchy
{
- #region LoggerCreationEvent
-
/// <summary>
/// Delegate used to handle logger creation event notifications.
/// </summary>
@@ -51,12 +50,7 @@
/// </remarks>
public class LoggerCreationEventArgs : EventArgs
{
- /// <summary>
- /// The <see cref="Logger"/> created
- /// </summary>
- private Logger m_log;
-
- /// <summary>
+ /// <summary>
/// Constructor
/// </summary>
/// <param name="log">The <see cref="Logger"/> that has been created.</param>
@@ -68,7 +62,7 @@
/// </remarks>
public LoggerCreationEventArgs(Logger log)
{
- m_log = log;
+ Logger = log;
}
/// <summary>
@@ -82,14 +76,9 @@
/// The <see cref="Logger"/> that has been created.
/// </para>
/// </remarks>
- public Logger Logger
- {
- get { return m_log; }
- }
+ public Logger Logger { get; }
}
- #endregion LoggerCreationEvent
-
/// <summary>
/// Hierarchical organization of loggers
/// </summary>
@@ -121,8 +110,6 @@
/// <author>Gert Driesen</author>
public class Hierarchy : LoggerRepositorySkeleton, IBasicRepositoryConfigurator, IXmlRepositoryConfigurator
{
- #region Public Events
-
/// <summary>
/// Event used to notify that a logger has been created.
/// </summary>
@@ -131,15 +118,7 @@
/// Event raised when a logger is created.
/// </para>
/// </remarks>
- public event LoggerCreationEventHandler LoggerCreatedEvent
- {
- add { m_loggerCreatedEvent += value; }
- remove { m_loggerCreatedEvent -= value; }
- }
-
- #endregion Public Events
-
- #region Public Instance Constructors
+ public event LoggerCreationEventHandler? LoggerCreatedEvent;
/// <summary>
/// Default constructor
@@ -193,20 +172,14 @@
/// </remarks>
public Hierarchy(PropertiesDictionary properties, ILoggerFactory loggerFactory) : base(properties)
{
- if (loggerFactory == null)
+ if (loggerFactory is null)
{
- throw new ArgumentNullException("loggerFactory");
+ throw new ArgumentNullException(nameof(loggerFactory));
}
m_defaultFactory = loggerFactory;
-
- m_ht = System.Collections.Hashtable.Synchronized(new System.Collections.Hashtable());
}
- #endregion Public Instance Constructors
-
- #region Public Instance Properties
-
/// <summary>
/// Has no appender warning been emitted
/// </summary>
@@ -216,11 +189,7 @@
/// about not having an appender warning.
/// </para>
/// </remarks>
- public bool EmittedNoAppenderWarning
- {
- get { return m_emittedNoAppenderWarning; }
- set { m_emittedNoAppenderWarning = value; }
- }
+ public bool EmittedNoAppenderWarning { get; set; }
/// <summary>
/// Get the root of this hierarchy
@@ -234,11 +203,11 @@
{
get
{
- if (m_root == null)
+ if (m_root is null)
{
lock (this)
{
- if (m_root == null)
+ if (m_root is null)
{
// Create the root logger
Logger root = m_defaultFactory.CreateLogger(this, null);
@@ -256,7 +225,6 @@
/// <summary>
/// Gets or sets the default <see cref="ILoggerFactory" /> instance.
/// </summary>
- /// <value>The default <see cref="ILoggerFactory" /></value>
/// <remarks>
/// <para>
/// The logger factory is used to create logger instances.
@@ -264,21 +232,13 @@
/// </remarks>
public ILoggerFactory LoggerFactory
{
- get { return m_defaultFactory; }
+ get => m_defaultFactory;
set
{
- if (value == null)
- {
- throw new ArgumentNullException("value");
- }
- m_defaultFactory = value;
+ m_defaultFactory = value ?? throw new ArgumentNullException(nameof(value));
}
}
- #endregion Public Instance Properties
-
- #region Override Implementation of LoggerRepositorySkeleton
-
/// <summary>
/// Test if a logger exists
/// </summary>
@@ -290,17 +250,15 @@
/// its reference, otherwise returns <c>null</c>.
/// </para>
/// </remarks>
- public override ILogger Exists(string name)
+ public override ILogger? Exists(string name)
{
- if (name == null)
+ if (name is null)
{
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
}
- lock (m_ht)
- {
- return m_ht[new LoggerKey(name)] as Logger;
- }
+ m_ht.TryGetValue(new LoggerKey(name), out object? o);
+ return o as Logger;
}
/// <summary>
@@ -319,20 +277,17 @@
// The accumulation in loggers is necessary because not all elements in
// ht are Logger objects as there might be some ProvisionNodes
// as well.
- lock (m_ht)
- {
- System.Collections.ArrayList loggers = new System.Collections.ArrayList(m_ht.Count);
+ var loggers = new List<ILogger>(m_ht.Count);
- // Iterate through m_ht values
- foreach (object node in m_ht.Values)
+ // Iterate through m_ht values
+ foreach (object node in m_ht.Values)
+ {
+ if (node is Logger logger)
{
- if (node is Logger)
- {
- loggers.Add(node);
- }
+ loggers.Add(logger);
}
- return (Logger[])loggers.ToArray(typeof(Logger));
}
+ return loggers.ToArray();
}
/// <summary>
@@ -356,7 +311,7 @@
{
if (name == null)
{
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
}
return GetLogger(name, m_defaultFactory);
@@ -378,34 +333,31 @@
/// </para>
/// <para>
/// The <c>Shutdown</c> method is careful to close nested
- /// appenders before closing regular appenders. This is allows
+ /// appenders before closing regular appenders. This allows
/// configurations where a regular appender is attached to a logger
/// and again to a nested appender.
/// </para>
/// </remarks>
public override void Shutdown()
{
- LogLog.Debug(declaringType, "Shutdown called on Hierarchy [" + this.Name + "]");
+ LogLog.Debug(declaringType, $"Shutdown called on Hierarchy [{Name}]");
// begin by closing nested appenders
Root.CloseNestedAppenders();
- lock (m_ht)
+ ILogger[] currentLoggers = GetCurrentLoggers();
+
+ foreach (Logger logger in currentLoggers.OfType<Logger>())
{
- ILogger[] currentLoggers = this.GetCurrentLoggers();
+ logger.CloseNestedAppenders();
+ }
- foreach (Logger logger in currentLoggers)
- {
- logger.CloseNestedAppenders();
- }
+ // then, remove all appenders
+ Root.RemoveAllAppenders();
- // then, remove all appenders
- Root.RemoveAllAppenders();
-
- foreach (Logger logger in currentLoggers)
- {
- logger.RemoveAllAppenders();
- }
+ foreach (Logger logger in currentLoggers.OfType<Logger>())
+ {
+ logger.RemoveAllAppenders();
}
base.Shutdown();
@@ -436,16 +388,12 @@
Root.Level = LevelMap.LookupWithDefault(Level.Debug);
Threshold = LevelMap.LookupWithDefault(Level.All);
- // the synchronization is needed to prevent hashtable surprises
- lock (m_ht)
- {
- Shutdown(); // nested locks are OK
+ Shutdown(); // nested locks are OK
- foreach (Logger l in this.GetCurrentLoggers())
- {
- l.Level = null;
- l.Additivity = true;
- }
+ foreach (Logger logger in GetCurrentLoggers().OfType<Logger>())
+ {
+ logger.Level = null;
+ logger.Additivity = true;
}
base.ResetConfiguration();
@@ -472,12 +420,15 @@
/// </remarks>
public override void Log(LoggingEvent logEvent)
{
- if (logEvent == null)
+ if (logEvent is null)
{
- throw new ArgumentNullException("logEvent");
+ throw new ArgumentNullException(nameof(logEvent));
}
- this.GetLogger(logEvent.LoggerName, m_defaultFactory).Log(logEvent);
+ if (logEvent.LoggerName is not null)
+ {
+ GetLogger(logEvent.LoggerName, m_defaultFactory).Log(logEvent);
+ }
}
/// <summary>
@@ -494,38 +445,31 @@
/// The list returned is unordered but does not contain duplicates.
/// </para>
/// </remarks>
- public override Appender.IAppender[] GetAppenders()
+ public override IAppender[] GetAppenders()
{
- System.Collections.ArrayList appenderList = new System.Collections.ArrayList();
+ var appenderList = new List<IAppender>();
CollectAppenders(appenderList, Root);
- foreach (Logger logger in GetCurrentLoggers())
+ foreach (Logger logger in GetCurrentLoggers().OfType<Logger>())
{
CollectAppenders(appenderList, logger);
}
- return (Appender.IAppender[])appenderList.ToArray(typeof(Appender.IAppender));
+ return appenderList.ToArray();
}
- #endregion Override Implementation of LoggerRepositorySkeleton
-
- #region Private Static Methods
-
/// <summary>
/// Collect the appenders from an <see cref="IAppenderAttachable"/>.
/// The appender may also be a container.
/// </summary>
- /// <param name="appenderList"></param>
- /// <param name="appender"></param>
- private static void CollectAppender(System.Collections.ArrayList appenderList, Appender.IAppender appender)
+ private static void CollectAppender(List<IAppender> appenderList, IAppender appender)
{
if (!appenderList.Contains(appender))
{
appenderList.Add(appender);
- IAppenderAttachable container = appender as IAppenderAttachable;
- if (container != null)
+ if (appender is IAppenderAttachable container)
{
CollectAppenders(appenderList, container);
}
@@ -535,20 +479,14 @@
/// <summary>
/// Collect the appenders from an <see cref="IAppenderAttachable"/> container
/// </summary>
- /// <param name="appenderList"></param>
- /// <param name="container"></param>
- private static void CollectAppenders(System.Collections.ArrayList appenderList, IAppenderAttachable container)
+ private static void CollectAppenders(List<IAppender> appenderList, IAppenderAttachable container)
{
- foreach (Appender.IAppender appender in container.Appenders)
+ foreach (IAppender appender in container.Appenders)
{
CollectAppender(appenderList, appender);
}
}
- #endregion
-
- #region Implementation of IBasicRepositoryConfigurator
-
/// <summary>
/// Initialize the log4net system using the specified appender
/// </summary>
@@ -580,7 +518,7 @@
/// </remarks>
protected void BasicRepositoryConfigure(params IAppender[] appenders)
{
- ArrayList configurationMessages = new ArrayList();
+ var configurationMessages = new List<LogLog>();
using (new LogLog.LogReceivedAdapter(configurationMessages))
{
@@ -598,10 +536,6 @@
OnConfigurationChanged(new ConfigurationChangedEventArgs(configurationMessages));
}
- #endregion Implementation of IBasicRepositoryConfigurator
-
- #region Implementation of IXmlRepositoryConfigurator
-
/// <summary>
/// Initialize the log4net system using the specified config
/// </summary>
@@ -624,11 +558,11 @@
/// </remarks>
protected void XmlRepositoryConfigure(System.Xml.XmlElement element)
{
- ArrayList configurationMessages = new ArrayList();
+ var configurationMessages = new List<LogLog>();
using (new LogLog.LogReceivedAdapter(configurationMessages))
{
- XmlHierarchyConfigurator config = new XmlHierarchyConfigurator(this);
+ var config = new XmlHierarchyConfigurator(this);
config.Configure(element);
}
@@ -640,10 +574,6 @@
OnConfigurationChanged(new ConfigurationChangedEventArgs(configurationMessages));
}
- #endregion Implementation of IXmlRepositoryConfigurator
-
- #region Public Instance Methods
-
/// <summary>
/// Test if this hierarchy is disabled for the specified <see cref="Level"/>.
/// </summary>
@@ -667,10 +597,9 @@
/// </remarks>
public bool IsDisabled(Level level)
{
- // Cast level to object for performance
- if ((object)level == null)
+ if (level is null)
{
- throw new ArgumentNullException("level");
+ throw new ArgumentNullException(nameof(level));
}
if (Configured)
@@ -700,10 +629,7 @@
/// </remarks>
public void Clear()
{
- lock (m_ht)
- {
- m_ht.Clear();
- }
+ m_ht.Clear();
}
/// <summary>
@@ -725,61 +651,52 @@
{
if (name == null)
{
- throw new ArgumentNullException("name");
+ throw new ArgumentNullException(nameof(name));
}
if (factory == null)
{
- throw new ArgumentNullException("factory");
+ throw new ArgumentNullException(nameof(factory));
}
- LoggerKey key = new LoggerKey(name);
+ var key = new LoggerKey(name);
// Synchronize to prevent write conflicts. Read conflicts (in
// GetEffectiveLevel() method) are possible only if variable
// assignments are non-atomic.
- lock (m_ht)
+ if (!m_ht.TryGetValue(key, out object? node))
{
- Logger logger = null;
+ return CreateLogger(null);
+ }
- Object node = m_ht[key];
- if (node == null)
+ if (node is Logger nodeLogger)
+ {
+ return nodeLogger;
+ }
+
+ if (node is ProvisionNode nodeProvisionNode)
+ {
+ return CreateLogger(l => UpdateChildren(nodeProvisionNode, l));
+ }
+
+ // It should be impossible to arrive here but let's keep the compiler happy.
+ return null!;
+
+ Logger CreateLogger(Action<Logger>? extraInit)
+ {
+ // Use GetOrAdd in case the logger was added after checking above.
+ return (Logger)m_ht.GetOrAdd(key, _ =>
{
- logger = factory.CreateLogger(this, name);
+ Logger logger = factory.CreateLogger(this, name);
logger.Hierarchy = this;
- m_ht[key] = logger;
+ extraInit?.Invoke(logger);
UpdateParents(logger);
OnLoggerCreationEvent(logger);
return logger;
- }
-
- Logger nodeLogger = node as Logger;
- if (nodeLogger != null)
- {
- return nodeLogger;
- }
-
- ProvisionNode nodeProvisionNode = node as ProvisionNode;
- if (nodeProvisionNode != null)
- {
- logger = factory.CreateLogger(this, name);
- logger.Hierarchy = this;
- m_ht[key] = logger;
- UpdateChildren(nodeProvisionNode, logger);
- UpdateParents(logger);
- OnLoggerCreationEvent(logger);
- return logger;
- }
-
- // It should be impossible to arrive here but let's keep the compiler happy.
- return null;
+ });
}
}
- #endregion Public Instance Methods
-
- #region Protected Instance Methods
-
/// <summary>
/// Sends a logger creation event to all registered listeners
/// </summary>
@@ -789,17 +706,9 @@
/// </remarks>
protected virtual void OnLoggerCreationEvent(Logger logger)
{
- LoggerCreationEventHandler handler = m_loggerCreatedEvent;
- if (handler != null)
- {
- handler(this, new LoggerCreationEventArgs(logger));
- }
+ LoggerCreatedEvent?.Invoke(this, new LoggerCreationEventArgs(logger));
}
- #endregion Protected Instance Methods
-
- #region Private Instance Methods
-
/// <summary>
/// Updates all the parents of the specified logger
/// </summary>
@@ -822,7 +731,7 @@
/// <description>
/// The entry is <paramref name="log"/>'s nearest existing parent. We
/// update <paramref name="log"/>'s parent field with this entry. We also break from
- /// he loop because updating our parent's parent is our parent's
+ /// the loop because updating our parent's parent is our parent's
/// responsibility.
/// </description>
/// </item>
@@ -846,40 +755,35 @@
{
string substr = name.Substring(0, i);
- LoggerKey key = new LoggerKey(substr); // simple constructor
- Object node = m_ht[key];
+ var key = new LoggerKey(substr);
+ m_ht.TryGetValue(key, out object? node);
+
// Create a provision node for a future parent.
- if (node == null)
+ if (node is null)
{
- ProvisionNode pn = new ProvisionNode(log);
- m_ht[key] = pn;
+ m_ht[key] = new ProvisionNode(log);
}
else
{
- Logger nodeLogger = node as Logger;
- if (nodeLogger != null)
+ if (node is Logger nodeLogger)
{
parentFound = true;
log.Parent = nodeLogger;
break; // no need to update the ancestors of the closest ancestor
}
+
+ if (node is ProvisionNode nodeProvisionNode)
+ {
+ nodeProvisionNode.Add(log);
+ }
else
{
- ProvisionNode nodeProvisionNode = node as ProvisionNode;
- if (nodeProvisionNode != null)
- {
- nodeProvisionNode.Add(log);
- }
- else
- {
- LogLog.Error(declaringType, "Unexpected object type [" + node.GetType() + "] in ht.", new LogException());
- }
+ LogLog.Error(declaringType, $"Unexpected object type [{node.GetType()}] in ht.", new LogException());
}
}
if (i == 0)
{
- // logger name starts with a dot
- // and we've hit the start
+ // logger name starts with a dot and we've hit the start
break;
}
}
@@ -887,15 +791,13 @@
// If we could not find any existing parents, then link with root.
if (!parentFound)
{
- log.Parent = this.Root;
+ log.Parent = Root;
}
}
/// <summary>
/// Replace a <see cref="ProvisionNode"/> with a <see cref="Logger"/> in the hierarchy.
/// </summary>
- /// <param name="pn"></param>
- /// <param name="log"></param>
/// <remarks>
/// <para>
/// We update the links for all the children that placed themselves
@@ -917,13 +819,11 @@
/// </remarks>
private static void UpdateChildren(ProvisionNode pn, Logger log)
{
- for (int i = 0; i < pn.Count; i++)
+ foreach (Logger childLogger in pn)
{
- Logger childLogger = (Logger)pn[i];
-
// Unless this child already points to a correct (lower) parent,
// make log.Parent point to childLogger.Parent and childLogger.Parent to log.
- if (!childLogger.Parent.Name.StartsWith(log.Name))
+ if (childLogger.Parent is not null && !childLogger.Parent.Name.StartsWith(log.Name, StringComparison.Ordinal))
{
log.Parent = childLogger.Parent;
childLogger.Parent = log;
@@ -937,27 +837,31 @@
/// <param name="levelEntry">the level values</param>
/// <remarks>
/// <para>
- /// Define or redefine a Level using the values in the <see cref="LevelEntry"/> argument
- /// </para>
- /// <para>
/// Supports setting levels via the configuration file.
/// </para>
/// </remarks>
internal void AddLevel(LevelEntry levelEntry)
{
- if (levelEntry == null) throw new ArgumentNullException("levelEntry");
- if (levelEntry.Name == null) throw new ArgumentNullException("levelEntry.Name");
+ if (levelEntry is null)
+ {
+ throw new ArgumentNullException(nameof(levelEntry));
+ }
+ if (levelEntry.Name is null)
+ {
+ throw new ArgumentNullException("levelEntry.Name");
+ }
// Lookup replacement value
if (levelEntry.Value == -1)
{
- Level previousLevel = LevelMap[levelEntry.Name];
- if (previousLevel == null)
+ if (LevelMap[levelEntry.Name] is Level previousLevel)
{
- throw new InvalidOperationException("Cannot redefine level [" + levelEntry.Name + "] because it is not defined in the LevelMap. To define the level supply the level value.");
+ levelEntry.Value = previousLevel.Value;
}
-
- levelEntry.Value = previousLevel.Value;
+ else
+ {
+ throw new InvalidOperationException($"Cannot redefine level [{levelEntry.Name}] because it is not defined in the LevelMap. To define the level supply the level value.");
+ }
}
LevelMap.Add(levelEntry.Name, levelEntry.Value, levelEntry.DisplayName);
@@ -971,12 +875,8 @@
/// A class to hold the value, name and display name for a level
/// </para>
/// </remarks>
- internal class LevelEntry
+ internal sealed class LevelEntry
{
- private int m_levelValue = -1;
- private string m_levelName = null;
- private string m_levelDisplayName = null;
-
/// <summary>
/// Value of the level
/// </summary>
@@ -986,11 +886,7 @@
/// up for the current level with the same name.
/// </para>
/// </remarks>
- public int Value
- {
- get { return m_levelValue; }
- set { m_levelValue = value; }
- }
+ public int Value { get; set; } = -1;
/// <summary>
/// Name of the level
@@ -1003,11 +899,7 @@
/// The name of the level.
/// </para>
/// </remarks>
- public string Name
- {
- get { return m_levelName; }
- set { m_levelName = value; }
- }
+ public string? Name { get; set; }
/// <summary>
/// Display name for the level
@@ -1020,11 +912,7 @@
/// The display name of the level.
/// </para>
/// </remarks>
- public string DisplayName
- {
- get { return m_levelDisplayName; }
- set { m_levelDisplayName = value; }
- }
+ public string? DisplayName { get; set; }
/// <summary>
/// Override <c>Object.ToString</c> to return sensible debug info
@@ -1032,7 +920,7 @@
/// <returns>string info about this object</returns>
public override string ToString()
{
- return "LevelEntry(Value=" + m_levelValue + ", Name=" + m_levelName + ", DisplayName=" + m_levelDisplayName + ")";
+ return $"LevelEntry(Value={Value}, Name={Name}, DisplayName={DisplayName})";
}
}
@@ -1050,28 +938,22 @@
/// </remarks>
internal void AddProperty(PropertyEntry propertyEntry)
{
- if (propertyEntry == null) throw new ArgumentNullException("propertyEntry");
- if (propertyEntry.Key == null) throw new ArgumentNullException("propertyEntry.Key");
+ if (propertyEntry is null)
+ {
+ throw new ArgumentNullException(nameof(propertyEntry));
+ }
+ if (propertyEntry.Key is null)
+ {
+ throw new ArgumentNullException("propertyEntry.Key");
+ }
Properties[propertyEntry.Key] = propertyEntry.Value;
}
- #endregion Private Instance Methods
-
- #region Private Instance Fields
-
private ILoggerFactory m_defaultFactory;
- private System.Collections.Hashtable m_ht;
- private Logger m_root;
-
- private bool m_emittedNoAppenderWarning = false;
-
- private event LoggerCreationEventHandler m_loggerCreatedEvent;
-
- #endregion Private Instance Fields
-
- #region Private Static Fields
+ private readonly ConcurrentDictionary<LoggerKey, object> m_ht = new(LoggerKey.ComparerInstance);
+ private Logger? m_root;
/// <summary>
/// The fully qualified type of the Hierarchy class.
@@ -1081,7 +963,5 @@
/// log message.
/// </remarks>
private static readonly Type declaringType = typeof(Hierarchy);
-
- #endregion Private Static Fields
}
}
diff --git a/src/log4net/Repository/Hierarchy/ILoggerFactory.cs b/src/log4net/Repository/Hierarchy/ILoggerFactory.cs
index 9826a97..5720d4e 100644
--- a/src/log4net/Repository/Hierarchy/ILoggerFactory.cs
+++ b/src/log4net/Repository/Hierarchy/ILoggerFactory.cs
@@ -59,6 +59,6 @@
/// must be returned.
/// </para>
/// </remarks>
- Logger CreateLogger(ILoggerRepository repository, string name);
+ Logger CreateLogger(ILoggerRepository repository, string? name);
}
}
diff --git a/src/log4net/Repository/Hierarchy/Logger.cs b/src/log4net/Repository/Hierarchy/Logger.cs
index 255a3b5..e04da5b 100644
--- a/src/log4net/Repository/Hierarchy/Logger.cs
+++ b/src/log4net/Repository/Hierarchy/Logger.cs
@@ -142,7 +142,6 @@
/// Gets or sets the <see cref="Hierarchy"/> where this
/// <c>Logger</c> instance is attached to.
/// </summary>
- /// <value>The hierarchy that this logger belongs to.</value>
/// <remarks>
/// <para>
/// This logger must be attached to a single <see cref="Hierarchy"/>.
@@ -160,11 +159,6 @@
/// <value>
/// The <see cref="Level"/> of this logger.
/// </value>
- /// <remarks>
- /// <para>
- /// The assigned <see cref="Level"/> can be <c>null</c>.
- /// </para>
- /// </remarks>
public virtual Level? Level { get; set; }
/// <summary>
@@ -174,10 +168,6 @@
/// <param name="newAppender">An appender to add to this logger</param>
/// <remarks>
/// <para>
- /// Add <paramref name="newAppender"/> to the list of appenders of this
- /// Logger instance.
- /// </para>
- /// <para>
/// If <paramref name="newAppender"/> is already in the list of
/// appenders, then it won't be added again.
/// </para>
@@ -205,14 +195,10 @@
/// Get the appenders contained in this logger as an
/// <see cref="System.Collections.ICollection"/>.
/// </summary>
- /// <returns>A collection of the appenders in this logger</returns>
- /// <remarks>
- /// <para>
- /// Get the appenders contained in this logger as an
- /// <see cref="System.Collections.ICollection"/>. If no appenders
+ /// <returns>
+ /// A collection of the appenders in this logger. If no appenders
/// can be found, then a <see cref="EmptyCollection"/> is returned.
- /// </para>
- /// </remarks>
+ /// </returns>
public virtual AppenderCollection Appenders
{
get
@@ -241,11 +227,6 @@
/// </summary>
/// <param name="name">The name of the appender to lookup</param>
/// <returns>The appender with the name specified, or <c>null</c>.</returns>
- /// <remarks>
- /// <para>
- /// Returns the named appender, or null if the appender is not found.
- /// </para>
- /// </remarks>
public virtual IAppender? GetAppender(string? name)
{
m_appenderLock.AcquireReaderLock();
@@ -265,13 +246,10 @@
}
/// <summary>
- /// Remove all previously added appenders from this Logger instance.
+ /// Removes all previously added appenders from this Logger instance.
/// </summary>
/// <remarks>
/// <para>
- /// Remove all previously added appenders from this Logger instance.
- /// </para>
- /// <para>
/// This is useful when re-reading configuration information.
/// </para>
/// </remarks>
@@ -299,7 +277,6 @@
/// <returns>The appender removed from the list</returns>
/// <remarks>
/// <para>
- /// Remove the appender passed as parameter form the list of appenders.
/// The appender removed is not closed.
/// If you are discarding the appender you must call
/// <see cref="IAppender.Close"/> on the appender removed.
@@ -329,7 +306,6 @@
/// <returns>The appender removed from the list</returns>
/// <remarks>
/// <para>
- /// Remove the named appender passed as parameter form the list of appenders.
/// The appender removed is not closed.
/// If you are discarding the appender you must call
/// <see cref="IAppender.Close"/> on the appender removed.
@@ -355,18 +331,11 @@
/// <summary>
/// Gets the logger name.
/// </summary>
- /// <value>
- /// The name of the logger.
- /// </value>
- /// <remarks>
- /// <para>
- /// The name of this logger
- /// </para>
- /// </remarks>
public virtual string Name { get; }
/// <summary>
- /// This generic form is intended to be used by wrappers.
+ /// Generates a logging event for the specified <paramref name="level"/> using
+ /// the <paramref name="message"/> and <paramref name="exception"/>.
/// </summary>
/// <param name="callerStackBoundaryDeclaringType">The declaring type of the method that is
/// the stack boundary into the logging system for this call.</param>
@@ -375,8 +344,7 @@
/// <param name="exception">The exception to log, including its stack trace.</param>
/// <remarks>
/// <para>
- /// Generate a logging event for the specified <paramref name="level"/> using
- /// the <paramref name="message"/> and <paramref name="exception"/>.
+ /// This generic form is intended to be used by wrappers.
/// </para>
/// <para>
/// This method must not throw any exception to the caller.
@@ -398,13 +366,13 @@
}
/// <summary>
- /// This is the most generic printing method that is intended to be used
- /// by wrappers.
+ /// Logs the specified logging event through this logger.
/// </summary>
/// <param name="logEvent">The event being logged.</param>
/// <remarks>
/// <para>
- /// Logs the specified logging event through this logger.
+ /// This is the most generic printing method that is intended to be used
+ /// by wrappers.
/// </para>
/// <para>
/// This method must not throw any exception to the caller.
@@ -437,9 +405,6 @@
/// </returns>
/// <remarks>
/// <para>
- /// Test if this logger is going to log events of the specified <paramref name="level"/>.
- /// </para>
- /// <para>
/// This method must not throw any exception to the caller.
/// </para>
/// </remarks>
@@ -467,15 +432,6 @@
/// Gets the <see cref="ILoggerRepository"/> where this
/// <c>Logger</c> instance is attached to.
/// </summary>
- /// <value>
- /// The <see cref="ILoggerRepository" /> that this logger belongs to.
- /// </value>
- /// <remarks>
- /// <para>
- /// Gets the <see cref="ILoggerRepository"/> where this
- /// <c>Logger</c> instance is attached to.
- /// </para>
- /// </remarks>
public ILoggerRepository? Repository => m_hierarchy;
/// <summary>
diff --git a/src/log4net/Repository/Hierarchy/LoggerKey.cs b/src/log4net/Repository/Hierarchy/LoggerKey.cs
index ee72165..de16cbc 100644
--- a/src/log4net/Repository/Hierarchy/LoggerKey.cs
+++ b/src/log4net/Repository/Hierarchy/LoggerKey.cs
@@ -18,6 +18,7 @@
#endregion
using System;
+using System.Collections.Generic;
namespace log4net.Repository.Hierarchy
{
@@ -38,10 +39,8 @@
/// </remarks>
/// <author>Nicko Cadell</author>
/// <author>Gert Driesen</author>
- internal sealed class LoggerKey
+ internal readonly struct LoggerKey
{
- #region Internal Instance Constructors
-
/// <summary>
/// Construct key with string name
/// </summary>
@@ -68,10 +67,6 @@
m_hashCache = name.GetHashCode();
}
- #endregion Internal Instance Constructors
-
- #region Override implementation of Object
-
/// <summary>
/// Returns a hash code for the current instance.
/// </summary>
@@ -86,43 +81,19 @@
return m_hashCache;
}
- /// <summary>
- /// Determines whether two <see cref="LoggerKey" /> instances
- /// are equal.
- /// </summary>
- /// <param name="obj">The <see cref="object" /> to compare with the current <see cref="LoggerKey" />.</param>
- /// <returns>
- /// <c>true</c> if the specified <see cref="object" /> is equal to the current <see cref="LoggerKey" />; otherwise, <c>false</c>.
- /// </returns>
- /// <remarks>
- /// <para>
- /// Compares the references of the interned strings.
- /// </para>
- /// </remarks>
- public override bool Equals(object obj)
- {
- // Compare reference type of this against argument
- if (((object)this) == obj)
- {
- return true;
- }
-
- LoggerKey objKey = obj as LoggerKey;
- if (objKey != null)
- {
- // Compare reference types rather than string's overloaded ==
- return (((object)m_name) == ((object)objKey.m_name));
- }
- return false;
- }
-
- #endregion
-
- #region Private Instance Fields
-
private readonly string m_name;
private readonly int m_hashCache;
- #endregion Private Instance Fields
+ public static Comparer ComparerInstance { get; } = new();
+
+ public sealed class Comparer : IEqualityComparer<LoggerKey>
+ {
+ public bool Equals(LoggerKey x, LoggerKey y)
+ {
+ return x.m_hashCache == y.m_hashCache && x.m_name == y.m_name;
+ }
+
+ public int GetHashCode(LoggerKey obj) => obj.m_hashCache;
+ }
}
-}
\ No newline at end of file
+}
diff --git a/src/log4net/Repository/Hierarchy/ProvisionNode.cs b/src/log4net/Repository/Hierarchy/ProvisionNode.cs
index 9262a47..4762851 100644
--- a/src/log4net/Repository/Hierarchy/ProvisionNode.cs
+++ b/src/log4net/Repository/Hierarchy/ProvisionNode.cs
@@ -17,8 +17,7 @@
//
#endregion
-using System;
-using System.Collections;
+using System.Collections.Generic;
namespace log4net.Repository.Hierarchy
{
@@ -38,7 +37,7 @@
/// </remarks>
/// <author>Nicko Cadell</author>
/// <author>Gert Driesen</author>
- internal sealed class ProvisionNode : ArrayList
+ internal sealed class ProvisionNode : List<Logger>
{
/// <summary>
/// Create a new provision node with child node
@@ -50,9 +49,9 @@
/// with the specified child logger.
/// </para>
/// </remarks>
- internal ProvisionNode(Logger log) : base()
+ internal ProvisionNode(Logger log)
{
- this.Add(log);
+ Add(log);
}
}
}
diff --git a/src/log4net/Repository/Hierarchy/XmlHierarchyConfigurator.cs b/src/log4net/Repository/Hierarchy/XmlHierarchyConfigurator.cs
index 7f149ac..a1d7769 100644
--- a/src/log4net/Repository/Hierarchy/XmlHierarchyConfigurator.cs
+++ b/src/log4net/Repository/Hierarchy/XmlHierarchyConfigurator.cs
@@ -19,6 +19,7 @@
using System;
using System.Collections;
+using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Xml;
@@ -48,8 +49,6 @@
Overwrite
}
- #region Public Instance Constructors
-
/// <summary>
/// Construct the configurator for a hierarchy
/// </summary>
@@ -63,13 +62,8 @@
public XmlHierarchyConfigurator(Hierarchy hierarchy)
{
m_hierarchy = hierarchy;
- m_appenderBag = new Hashtable();
}
- #endregion Public Instance Constructors
-
- #region Public Instance Methods
-
/// <summary>
/// Configure the hierarchy by parsing a DOM tree of XML elements.
/// </summary>
@@ -79,9 +73,9 @@
/// Configure the hierarchy by parsing a DOM tree of XML elements.
/// </para>
/// </remarks>
- public void Configure(XmlElement element)
+ public void Configure(XmlElement? element)
{
- if (element == null || m_hierarchy == null)
+ if (element is null)
{
return;
}
@@ -90,7 +84,7 @@
if (rootElementName != CONFIGURATION_TAG)
{
- LogLog.Error(declaringType, "Xml element is - not a <" + CONFIGURATION_TAG + "> element.");
+ LogLog.Error(declaringType, $"Xml element is - not a <{CONFIGURATION_TAG}> element.");
return;
}
@@ -98,7 +92,7 @@
{
// Look for a emitDebug attribute to enable internal debug
string emitDebugAttribute = element.GetAttribute(EMIT_INTERNAL_DEBUG_ATTR);
- LogLog.Debug(declaringType, EMIT_INTERNAL_DEBUG_ATTR + " attribute [" + emitDebugAttribute + "].");
+ LogLog.Debug(declaringType, $"{EMIT_INTERNAL_DEBUG_ATTR} attribute [{emitDebugAttribute}].");
if (emitDebugAttribute.Length > 0 && emitDebugAttribute != "null")
{
@@ -106,7 +100,7 @@
}
else
{
- LogLog.Debug(declaringType, "Ignoring " + EMIT_INTERNAL_DEBUG_ATTR + " attribute.");
+ LogLog.Debug(declaringType, $"Ignoring {EMIT_INTERNAL_DEBUG_ATTR} attribute.");
}
}
@@ -114,7 +108,7 @@
{
// Look for a debug attribute to enable internal debug
string debugAttribute = element.GetAttribute(INTERNAL_DEBUG_ATTR);
- LogLog.Debug(declaringType, INTERNAL_DEBUG_ATTR + " attribute [" + debugAttribute + "].");
+ LogLog.Debug(declaringType, $"{INTERNAL_DEBUG_ATTR} attribute [{debugAttribute}].");
if (debugAttribute.Length > 0 && debugAttribute != "null")
{
@@ -122,38 +116,45 @@
}
else
{
- LogLog.Debug(declaringType, "Ignoring " + INTERNAL_DEBUG_ATTR + " attribute.");
+ LogLog.Debug(declaringType, $"Ignoring {INTERNAL_DEBUG_ATTR} attribute.");
}
string confDebug = element.GetAttribute(CONFIG_DEBUG_ATTR);
if (confDebug.Length > 0 && confDebug != "null")
{
- LogLog.Warn(declaringType, "The \"" + CONFIG_DEBUG_ATTR + "\" attribute is deprecated.");
- LogLog.Warn(declaringType, "Use the \"" + INTERNAL_DEBUG_ATTR + "\" attribute instead.");
+ LogLog.Warn(declaringType, $"The \"{CONFIG_DEBUG_ATTR}\" attribute is deprecated.");
+ LogLog.Warn(declaringType, $"Use the \"{INTERNAL_DEBUG_ATTR}\" attribute instead.");
LogLog.InternalDebugging = OptionConverter.ToBoolean(confDebug, true);
}
}
// Default mode is merge
- ConfigUpdateMode configUpdateMode = ConfigUpdateMode.Merge;
+ ConfigUpdateMode? configUpdateMode = ConfigUpdateMode.Merge;
// Look for the config update attribute
- string configUpdateModeAttribute = element.GetAttribute(CONFIG_UPDATE_MODE_ATTR);
- if (configUpdateModeAttribute != null && configUpdateModeAttribute.Length > 0)
+ string? configUpdateModeAttribute = element.GetAttribute(CONFIG_UPDATE_MODE_ATTR);
+ if (!string.IsNullOrEmpty(configUpdateModeAttribute))
{
// Parse the attribute
try
{
- configUpdateMode = (ConfigUpdateMode)OptionConverter.ConvertStringTo(typeof(ConfigUpdateMode), configUpdateModeAttribute);
+ if (OptionConverter.ConvertStringTo(typeof(ConfigUpdateMode), configUpdateModeAttribute) is ConfigUpdateMode mode)
+ {
+ configUpdateMode = mode;
+ }
+ else
+ {
+ LogLog.Error(declaringType, $"Invalid {CONFIG_UPDATE_MODE_ATTR} attribute value [{configUpdateModeAttribute}]");
+ }
}
catch
{
- LogLog.Error(declaringType, "Invalid " + CONFIG_UPDATE_MODE_ATTR + " attribute value [" + configUpdateModeAttribute + "]");
+ LogLog.Error(declaringType, $"Invalid {CONFIG_UPDATE_MODE_ATTR} attribute value [{configUpdateModeAttribute}]");
}
}
// IMPL: The IFormatProvider argument to Enum.ToString() is deprecated in .NET 2.0
- LogLog.Debug(declaringType, "Configuration update mode [" + configUpdateMode.ToString() + "].");
+ LogLog.Debug(declaringType, $"Configuration update mode [{configUpdateMode}].");
// Only reset configuration if overwrite flag specified
if (configUpdateMode == ConfigUpdateMode.Overwrite)
@@ -206,27 +207,23 @@
// Lastly set the hierarchy threshold
string thresholdStr = element.GetAttribute(THRESHOLD_ATTR);
- LogLog.Debug(declaringType, "Hierarchy Threshold [" + thresholdStr + "]");
+ LogLog.Debug(declaringType, $"Hierarchy Threshold [{thresholdStr}]");
if (thresholdStr.Length > 0 && thresholdStr != "null")
{
Level thresholdLevel = (Level)ConvertStringTo(typeof(Level), thresholdStr);
- if (thresholdLevel != null)
+ if (thresholdLevel is not null)
{
m_hierarchy.Threshold = thresholdLevel;
}
else
{
- LogLog.Warn(declaringType, "Unable to set hierarchy threshold using value [" + thresholdStr + "] (with acceptable conversion types)");
+ LogLog.Warn(declaringType, $"Unable to set hierarchy threshold using value [{thresholdStr}] (with acceptable conversion types)");
}
}
// Done reading config
}
- #endregion Public Instance Methods
-
- #region Protected Instance Methods
-
/// <summary>
/// Parse appenders by IDREF.
/// </summary>
@@ -238,47 +235,42 @@
/// the appender.
/// </para>
/// </remarks>
- protected IAppender FindAppenderByReference(XmlElement appenderRef)
+ protected IAppender? FindAppenderByReference(XmlElement appenderRef)
{
- string appenderName = appenderRef.GetAttribute(REF_ATTR);
+ string? appenderName = appenderRef.GetAttribute(REF_ATTR);
- IAppender appender = (IAppender)m_appenderBag[appenderName];
- if (appender != null)
+ if (m_appenderBag.TryGetValue(appenderName, out IAppender? appender))
{
return appender;
}
- else
+
+ // Find the element with that id
+ XmlElement? element = null;
+
+ if (!string.IsNullOrEmpty(appenderName) && appenderRef.OwnerDocument is not null)
{
- // Find the element with that id
- XmlElement element = null;
-
- if (appenderName != null && appenderName.Length > 0)
+ foreach (XmlElement curAppenderElement in appenderRef.OwnerDocument.GetElementsByTagName(APPENDER_TAG))
{
- foreach (XmlElement curAppenderElement in appenderRef.OwnerDocument.GetElementsByTagName(APPENDER_TAG))
+ if (curAppenderElement.GetAttribute("name") == appenderName)
{
- if (curAppenderElement.GetAttribute("name") == appenderName)
- {
- element = curAppenderElement;
- break;
- }
+ element = curAppenderElement;
+ break;
}
}
-
- if (element == null)
- {
- LogLog.Error(declaringType, "XmlHierarchyConfigurator: No appender named [" + appenderName + "] could be found.");
- return null;
- }
- else
- {
- appender = ParseAppender(element);
- if (appender != null)
- {
- m_appenderBag[appenderName] = appender;
- }
- return appender;
- }
}
+
+ if (element is null)
+ {
+ LogLog.Error(declaringType, $"XmlHierarchyConfigurator: No appender named [{appenderName}] could be found.");
+ return null;
+ }
+
+ appender = ParseAppender(element);
+ if (appender is not null)
+ {
+ m_appenderBag[appenderName] = appender;
+ }
+ return appender;
}
/// <summary>
@@ -292,20 +284,20 @@
/// the appender instance.
/// </para>
/// </remarks>
- protected IAppender ParseAppender(XmlElement appenderElement)
+ protected IAppender? ParseAppender(XmlElement appenderElement)
{
string appenderName = appenderElement.GetAttribute(NAME_ATTR);
string typeName = appenderElement.GetAttribute(TYPE_ATTR);
- LogLog.Debug(declaringType, "Loading Appender [" + appenderName + "] type: [" + typeName + "]");
+ LogLog.Debug(declaringType, $"Loading Appender [{appenderName}] type: [{typeName}]");
try
{
- IAppender appender = (IAppender)Activator.CreateInstance(SystemInfo.GetTypeFromString(typeName, true, true));
+ IAppender appender = (IAppender)Activator.CreateInstance(SystemInfo.GetTypeFromString(typeName, true, true)!);
appender.Name = appenderName;
foreach (XmlNode currentNode in appenderElement.ChildNodes)
{
- /* We're only interested in Elements */
+ // We're only interested in Elements
if (currentNode.NodeType == XmlNodeType.Element)
{
XmlElement currentElement = (XmlElement)currentNode;
@@ -315,20 +307,19 @@
{
string refName = currentElement.GetAttribute(REF_ATTR);
- IAppenderAttachable appenderContainer = appender as IAppenderAttachable;
- if (appenderContainer != null)
+ if (appender is IAppenderAttachable appenderContainer)
{
- LogLog.Debug(declaringType, "Attaching appender named [" + refName + "] to appender named [" + appender.Name + "].");
+ LogLog.Debug(declaringType, $"Attaching appender named [{refName}] to appender named [{appender.Name}].");
IAppender referencedAppender = FindAppenderByReference(currentElement);
- if (referencedAppender != null)
+ if (referencedAppender is not null)
{
appenderContainer.AddAppender(referencedAppender);
}
}
else
{
- LogLog.Error(declaringType, "Requesting attachment of appender named [" + refName + "] to appender named [" + appender.Name + "] which does not implement log4net.Core.IAppenderAttachable.");
+ LogLog.Error(declaringType, $"Requesting attachment of appender named [{refName}] to appender named [{appender.Name}] which does not implement log4net.Core.IAppenderAttachable.");
}
}
else
@@ -339,20 +330,19 @@
}
}
- IOptionHandler optionHandler = appender as IOptionHandler;
- if (optionHandler != null)
+ if (appender is IOptionHandler optionHandler)
{
optionHandler.ActivateOptions();
}
- LogLog.Debug(declaringType, "Created Appender [" + appenderName + "]");
+ LogLog.Debug(declaringType, $"Created Appender [{appenderName}]");
return appender;
}
catch (Exception ex)
{
// Yes, it's ugly. But all exceptions point to the same problem: we can't create an Appender
- LogLog.Error(declaringType, "Could not create Appender [" + appenderName + "] of type [" + typeName + "]. Reported error follows.", ex);
+ LogLog.Error(declaringType, $"Could not create Appender [{appenderName}] of type [{typeName}]. Reported error follows.", ex);
return null;
}
}
@@ -371,19 +361,21 @@
// Create a new log4net.Logger object from the <logger> element.
string loggerName = loggerElement.GetAttribute(NAME_ATTR);
- LogLog.Debug(declaringType, "Retrieving an instance of log4net.Repository.Logger for logger [" + loggerName + "].");
- Logger log = m_hierarchy.GetLogger(loggerName) as Logger;
+ LogLog.Debug(declaringType, $"Retrieving an instance of log4net.Repository.Logger for logger [{loggerName}].");
// Setting up a logger needs to be an atomic operation, in order
// to protect potential log operations while logger
// configuration is in progress.
- lock (log)
+ if (m_hierarchy.GetLogger(loggerName) is Logger log)
{
- bool additivity = OptionConverter.ToBoolean(loggerElement.GetAttribute(ADDITIVITY_ATTR), true);
+ lock (log)
+ {
+ bool additivity = OptionConverter.ToBoolean(loggerElement.GetAttribute(ADDITIVITY_ATTR), true);
- LogLog.Debug(declaringType, "Setting [" + log.Name + "] additivity to [" + additivity + "].");
- log.Additivity = additivity;
- ParseChildrenOfLoggerElement(loggerElement, log, false);
+ LogLog.Debug(declaringType, $"Setting [{log.Name}] additivity to [{additivity}].");
+ log.Additivity = additivity;
+ ParseChildrenOfLoggerElement(loggerElement, log, false);
+ }
}
}
@@ -433,17 +425,17 @@
{
IAppender appender = FindAppenderByReference(currentElement);
string refName = currentElement.GetAttribute(REF_ATTR);
- if (appender != null)
+ if (appender is not null)
{
- LogLog.Debug(declaringType, "Adding appender named [" + refName + "] to logger [" + log.Name + "].");
+ LogLog.Debug(declaringType, $"Adding appender named [{refName}] to logger [{log.Name}].");
log.AddAppender(appender);
}
else
{
- LogLog.Error(declaringType, "Appender named [" + refName + "] not found.");
+ LogLog.Error(declaringType, $"Appender named [{refName}] not found.");
}
}
- else if (currentElement.LocalName == LEVEL_TAG || currentElement.LocalName == PRIORITY_TAG)
+ else if (currentElement.LocalName is LEVEL_TAG or PRIORITY_TAG)
{
ParseLevel(currentElement, log, isRoot);
}
@@ -454,8 +446,7 @@
}
}
- IOptionHandler optionHandler = log as IOptionHandler;
- if (optionHandler != null)
+ if (log is IOptionHandler optionHandler)
{
optionHandler.ActivateOptions();
}
@@ -475,23 +466,21 @@
string renderingClassName = element.GetAttribute(RENDERING_TYPE_ATTR);
string renderedClassName = element.GetAttribute(RENDERED_TYPE_ATTR);
- LogLog.Debug(declaringType, "Rendering class [" + renderingClassName + "], Rendered class [" + renderedClassName + "].");
+ LogLog.Debug(declaringType, $"Rendering class [{renderingClassName}], Rendered class [{renderedClassName}].");
IObjectRenderer renderer = (IObjectRenderer)OptionConverter.InstantiateByClassName(renderingClassName, typeof(IObjectRenderer), null);
- if (renderer == null)
+ if (renderer is null)
{
- LogLog.Error(declaringType, "Could not instantiate renderer [" + renderingClassName + "].");
+ LogLog.Error(declaringType, $"Could not instantiate renderer [{renderingClassName}].");
return;
}
- else
+
+ try
{
- try
- {
- m_hierarchy.RendererMap.Put(SystemInfo.GetTypeFromString(renderedClassName, true, true), renderer);
- }
- catch (Exception e)
- {
- LogLog.Error(declaringType, "Could not find class [" + renderedClassName + "].", e);
- }
+ m_hierarchy.RendererMap.Put(SystemInfo.GetTypeFromString(renderedClassName, true, true)!, renderer);
+ }
+ catch (Exception e)
+ {
+ LogLog.Error(declaringType, $"Could not find class [{renderedClassName}].", e);
}
}
@@ -515,7 +504,7 @@
}
string levelStr = element.GetAttribute(VALUE_ATTR);
- LogLog.Debug(declaringType, "Logger [" + loggerName + "] Level string is [" + levelStr + "].");
+ LogLog.Debug(declaringType, $"Logger [{loggerName}] Level string is [{levelStr}].");
if (INHERITED == levelStr)
{
@@ -525,20 +514,20 @@
}
else
{
- LogLog.Debug(declaringType, "Logger [" + loggerName + "] level set to inherit from parent.");
+ LogLog.Debug(declaringType, $"Logger [{loggerName}] level set to inherit from parent.");
log.Level = null;
}
}
else
{
- log.Level = log.Hierarchy.LevelMap[levelStr];
- if (log.Level == null)
+ log.Level = log.Hierarchy?.LevelMap[levelStr];
+ if (log.Level is null)
{
- LogLog.Error(declaringType, "Undefined level [" + levelStr + "] on Logger [" + loggerName + "].");
+ LogLog.Error(declaringType, $"Undefined level [{levelStr}] on Logger [{loggerName}].");
}
else
{
- LogLog.Debug(declaringType, "Logger [" + loggerName + "] level set to [name=\"" + log.Level.Name + "\",value=" + log.Level.Value + "].");
+ LogLog.Debug(declaringType, $"Logger [{loggerName}] level set to [name=\"{log.Level.Name}\",value={log.Level.Value}].");
}
}
}
@@ -565,21 +554,20 @@
string name = element.GetAttribute(NAME_ATTR);
// If the name attribute does not exist then use the name of the element
- if (element.LocalName != PARAM_TAG || name == null || name.Length == 0)
+ if (element.LocalName != PARAM_TAG || name.Length == 0)
{
name = element.LocalName;
}
// Look for the property on the target object
Type targetType = target.GetType();
- Type propertyType = null;
+ Type? propertyType = null;
- PropertyInfo propInfo = null;
- MethodInfo methInfo = null;
+ MethodInfo? methInfo = null;
// Try to find a writable property
- propInfo = targetType.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.IgnoreCase);
- if (propInfo != null && propInfo.CanWrite)
+ PropertyInfo? propInfo = targetType.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.IgnoreCase);
+ if (propInfo is not null && propInfo.CanWrite)
{
// found a property
propertyType = propInfo.PropertyType;
@@ -590,22 +578,21 @@
// look for a method with the signature Add<property>(type)
methInfo = FindMethodInfo(targetType, name);
-
- if (methInfo != null)
+ if (methInfo is not null)
{
propertyType = methInfo.GetParameters()[0].ParameterType;
}
}
- if (propertyType == null)
+ if (propertyType is null)
{
- LogLog.Error(declaringType, "XmlHierarchyConfigurator: Cannot find Property [" + name + "] to set object on [" + target.ToString() + "]");
+ LogLog.Error(declaringType, $"XmlHierarchyConfigurator: Cannot find Property [{name}] to set object on [{target}]");
}
else
{
- string propertyValue = null;
+ string? propertyValue = null;
- if (element.GetAttributeNode(VALUE_ATTR) != null)
+ if (element.GetAttributeNode(VALUE_ATTR) is not null)
{
propertyValue = element.GetAttribute(VALUE_ATTR);
}
@@ -614,9 +601,9 @@
// Concatenate the CDATA and Text nodes together
foreach (XmlNode childNode in element.ChildNodes)
{
- if (childNode.NodeType == XmlNodeType.CDATA || childNode.NodeType == XmlNodeType.Text)
+ if (childNode.NodeType is XmlNodeType.CDATA or XmlNodeType.Text)
{
- if (propertyValue == null)
+ if (propertyValue is null)
{
propertyValue = childNode.InnerText;
}
@@ -628,7 +615,7 @@
}
}
- if (propertyValue != null)
+ if (propertyValue is not null)
{
try
{
@@ -652,14 +639,14 @@
// Check if a specific subtype is specified on the element using the 'type' attribute
string subTypeString = element.GetAttribute(TYPE_ATTR);
- if (subTypeString != null && subTypeString.Length > 0)
+ if (subTypeString.Length > 0)
{
// Read the explicit subtype
try
{
- Type subType = SystemInfo.GetTypeFromString(subTypeString, true, true);
+ Type subType = SystemInfo.GetTypeFromString(subTypeString, true, true)!;
- LogLog.Debug(declaringType, "Parameter [" + name + "] specified subtype [" + subType.FullName + "]");
+ LogLog.Debug(declaringType, $"Parameter [{name}] specified subtype [{subType.FullName}]");
if (!propertyType.IsAssignableFrom(subType))
{
@@ -669,12 +656,12 @@
// Must re-convert to the real property type
parsedObjectConversionTargetType = propertyType;
- // Use sub type as intermediary type
+ // Use subtype as intermediary type
propertyType = subType;
}
else
{
- LogLog.Error(declaringType, "subtype [" + subType.FullName + "] set on [" + name + "] is not a subclass of property type [" + propertyType.FullName + "] and there are no acceptable type conversions.");
+ LogLog.Error(declaringType, $"subtype [{subType.FullName}] set on [{name}] is not a subclass of property type [{propertyType.FullName}] and there are no acceptable type conversions.");
}
}
else
@@ -686,28 +673,28 @@
}
catch (Exception ex)
{
- LogLog.Error(declaringType, "Failed to find type [" + subTypeString + "] set on [" + name + "]", ex);
+ LogLog.Error(declaringType, $"Failed to find type [{subTypeString}] set on [{name}]", ex);
}
}
// Now try to convert the string value to an acceptable type
// to pass to this property.
- object convertedValue = ConvertStringTo(propertyType, propertyValue);
+ object? convertedValue = ConvertStringTo(propertyType, propertyValue);
// Check if we need to do an additional conversion
- if (convertedValue != null && parsedObjectConversionTargetType != null)
+ if (convertedValue is not null && parsedObjectConversionTargetType is not null)
{
- LogLog.Debug(declaringType, "Performing additional conversion of value from [" + convertedValue.GetType().Name + "] to [" + parsedObjectConversionTargetType.Name + "]");
+ LogLog.Debug(declaringType, $"Performing additional conversion of value from [{convertedValue.GetType().Name}] to [{parsedObjectConversionTargetType.Name}]");
convertedValue = OptionConverter.ConvertTypeTo(convertedValue, parsedObjectConversionTargetType);
}
- if (convertedValue != null)
+ if (convertedValue is not null)
{
- if (propInfo != null)
+ if (propInfo is not null)
{
// Got a converted result
- LogLog.Debug(declaringType, "Setting Property [" + propInfo.Name + "] to " + convertedValue.GetType().Name + " value [" + convertedValue.ToString() + "]");
+ LogLog.Debug(declaringType, $"Setting Property [{propInfo.Name}] to {convertedValue.GetType().Name} value [{convertedValue}]");
try
{
@@ -716,33 +703,33 @@
}
catch (TargetInvocationException targetInvocationEx)
{
- LogLog.Error(declaringType, "Failed to set parameter [" + propInfo.Name + "] on object [" + target + "] using value [" + convertedValue + "]", targetInvocationEx.InnerException);
+ LogLog.Error(declaringType, $"Failed to set parameter [{propInfo.Name}] on object [{target}] using value [{convertedValue}]", targetInvocationEx.InnerException);
}
}
- else if (methInfo != null)
+ else
{
// Got a converted result
- LogLog.Debug(declaringType, "Setting Collection Property [" + methInfo.Name + "] to " + convertedValue.GetType().Name + " value [" + convertedValue.ToString() + "]");
+ LogLog.Debug(declaringType, $"Setting Collection Property [{methInfo.Name}] to {convertedValue.GetType().Name} value [{convertedValue}]");
try
{
// Pass to the property
- methInfo.Invoke(target, BindingFlags.InvokeMethod, null, new object[] { convertedValue }, CultureInfo.InvariantCulture);
+ methInfo.Invoke(target, BindingFlags.InvokeMethod, null, new[] { convertedValue }, CultureInfo.InvariantCulture);
}
catch (TargetInvocationException targetInvocationEx)
{
- LogLog.Error(declaringType, "Failed to set parameter [" + name + "] on object [" + target + "] using value [" + convertedValue + "]", targetInvocationEx.InnerException);
+ LogLog.Error(declaringType, $"Failed to set parameter [{name}] on object [{target}] using value [{convertedValue}]", targetInvocationEx.InnerException);
}
}
}
else
{
- LogLog.Warn(declaringType, "Unable to set property [" + name + "] on object [" + target + "] using value [" + propertyValue + "] (with acceptable conversion types)");
+ LogLog.Warn(declaringType, $"Unable to set property [{name}] on object [{target}] using value [{propertyValue}] (with acceptable conversion types)");
}
}
else
{
- object createdObject = null;
+ object? createdObject;
if (propertyType == typeof(string) && !HasAttributesOrElements(element))
{
@@ -751,12 +738,12 @@
// This is necessary because while the String is a class it does not have
// a default constructor that creates an empty string, which is the behavior
// we are trying to simulate and would be expected from CreateObjectFromXml
- createdObject = "";
+ createdObject = string.Empty;
}
else
{
// No value specified
- Type defaultObjectType = null;
+ Type? defaultObjectType = null;
if (IsTypeConstructible(propertyType))
{
defaultObjectType = propertyType;
@@ -765,16 +752,16 @@
createdObject = CreateObjectFromXml(element, defaultObjectType, propertyType);
}
- if (createdObject == null)
+ if (createdObject is null)
{
- LogLog.Error(declaringType, "Failed to create object to set param: " + name);
+ LogLog.Error(declaringType, $"Failed to create object to set param: {name}");
}
else
{
- if (propInfo != null)
+ if (propInfo is not null)
{
// Got a converted result
- LogLog.Debug(declaringType, "Setting Property [" + propInfo.Name + "] to object [" + createdObject + "]");
+ LogLog.Debug(declaringType, $"Setting Property [{propInfo.Name}] to object [{createdObject}]");
try
{
@@ -783,22 +770,22 @@
}
catch (TargetInvocationException targetInvocationEx)
{
- LogLog.Error(declaringType, "Failed to set parameter [" + propInfo.Name + "] on object [" + target + "] using value [" + createdObject + "]", targetInvocationEx.InnerException);
+ LogLog.Error(declaringType, $"Failed to set parameter [{propInfo.Name}] on object [{target}] using value [{createdObject}]", targetInvocationEx.InnerException);
}
}
- else if (methInfo != null)
+ else
{
// Got a converted result
- LogLog.Debug(declaringType, "Setting Collection Property [" + methInfo.Name + "] to object [" + createdObject + "]");
+ LogLog.Debug(declaringType, $"Setting Collection Property [{methInfo.Name}] to object [{createdObject}]");
try
{
// Pass to the property
- methInfo.Invoke(target, BindingFlags.InvokeMethod, null, new object[] { createdObject }, CultureInfo.InvariantCulture);
+ methInfo.Invoke(target, BindingFlags.InvokeMethod, null, new[] { createdObject }, CultureInfo.InvariantCulture);
}
catch (TargetInvocationException targetInvocationEx)
{
- LogLog.Error(declaringType, "Failed to set parameter [" + methInfo.Name + "] on object [" + target + "] using value [" + createdObject + "]", targetInvocationEx.InnerException);
+ LogLog.Error(declaringType, $"Failed to set parameter [{methInfo.Name}] on object [{target}] using value [{createdObject}]", targetInvocationEx.InnerException);
}
}
}
@@ -832,8 +819,8 @@
{
if (type.IsClass && !type.IsAbstract)
{
- ConstructorInfo defaultConstructor = type.GetConstructor(new Type[0]);
- if (defaultConstructor != null && !defaultConstructor.IsAbstract && !defaultConstructor.IsPrivate)
+ ConstructorInfo defaultConstructor = type.GetConstructor(Type.EmptyTypes);
+ if (defaultConstructor is not null && !defaultConstructor.IsAbstract && !defaultConstructor.IsPrivate)
{
return true;
}
@@ -854,7 +841,7 @@
/// The method must take a single parameter.
/// </para>
/// </remarks>
- private MethodInfo FindMethodInfo(Type targetType, string name)
+ private static MethodInfo? FindMethodInfo(Type targetType, string name)
{
string requiredMethodNameA = name;
string requiredMethodNameB = "Add" + name;
@@ -873,7 +860,7 @@
// Found matching method name
// Look for version with one arg only
- System.Reflection.ParameterInfo[] methParams = methInfo.GetParameters();
+ ParameterInfo[] methParams = methInfo.GetParameters();
if (methParams.Length == 1)
{
return methInfo;
@@ -895,17 +882,17 @@
/// <c>null</c> when the conversion could not be performed.
/// </para>
/// </returns>
- protected object ConvertStringTo(Type type, string value)
+ protected object? ConvertStringTo(Type type, string value)
{
// Hack to allow use of Level in property
if (typeof(Level) == type)
{
// Property wants a level
- Level levelValue = m_hierarchy.LevelMap[value];
+ Level? levelValue = m_hierarchy.LevelMap[value];
- if (levelValue == null)
+ if (levelValue is null)
{
- LogLog.Error(declaringType, "XmlHierarchyConfigurator: Unknown Level Specified [" + value + "]");
+ LogLog.Error(declaringType, $"XmlHierarchyConfigurator: Unknown Level Specified [{value}]");
}
return levelValue;
@@ -932,24 +919,22 @@
/// <paramref name="typeConstraint"/> type.
/// </para>
/// </remarks>
- protected object CreateObjectFromXml(XmlElement element, Type defaultTargetType, Type typeConstraint)
+ protected object? CreateObjectFromXml(XmlElement element, Type? defaultTargetType, Type? typeConstraint)
{
- Type objectType = null;
+ Type? objectType;
// Get the object type
string objectTypeString = element.GetAttribute(TYPE_ATTR);
- if (objectTypeString == null || objectTypeString.Length == 0)
+ if (objectTypeString.Length == 0)
{
- if (defaultTargetType == null)
+ if (defaultTargetType is null)
{
- LogLog.Error(declaringType, "Object type not specified. Cannot create object of type [" + typeConstraint.FullName + "]. Missing Value or Type.");
+ LogLog.Error(declaringType, $"Object type not specified. Cannot create object of type [{typeConstraint?.FullName}]. Missing Value or Type.");
return null;
}
- else
- {
- // Use the default object type
- objectType = defaultTargetType;
- }
+
+ // Use the default object type
+ objectType = defaultTargetType;
}
else
{
@@ -960,7 +945,7 @@
}
catch (Exception ex)
{
- LogLog.Error(declaringType, "Failed to find type [" + objectTypeString + "]", ex);
+ LogLog.Error(declaringType, $"Failed to find type [{objectTypeString}]", ex);
return null;
}
}
@@ -968,7 +953,7 @@
bool requiresConversion = false;
// Got the object type. Check that it meets the typeConstraint
- if (typeConstraint != null)
+ if (typeConstraint is not null)
{
if (!typeConstraint.IsAssignableFrom(objectType))
{
@@ -979,21 +964,22 @@
}
else
{
- LogLog.Error(declaringType, "Object type [" + objectType.FullName + "] is not assignable to type [" + typeConstraint.FullName + "]. There are no acceptable type conversions.");
+ LogLog.Error(declaringType, $"Object type [{objectType!.FullName}] is not assignable to type [{typeConstraint.FullName}]. There are no acceptable type conversions.");
return null;
}
}
}
// Create using the default constructor
- object createdObject = null;
+ object? createdObject;
try
{
- createdObject = Activator.CreateInstance(objectType);
+ createdObject = Activator.CreateInstance(objectType!);
}
catch (Exception createInstanceEx)
{
- LogLog.Error(declaringType, "XmlHierarchyConfigurator: Failed to construct object of type [" + objectType.FullName + "] Exception: " + createInstanceEx.ToString());
+ LogLog.Error(declaringType, $"XmlHierarchyConfigurator: Failed to construct object of type [{objectType!.FullName}] Exception: {createInstanceEx}");
+ return null;
}
// Set any params on object
@@ -1006,8 +992,7 @@
}
// Check if we need to call ActivateOptions
- IOptionHandler optionHandler = createdObject as IOptionHandler;
- if (optionHandler != null)
+ if (createdObject is IOptionHandler optionHandler)
{
optionHandler.ActivateOptions();
}
@@ -1019,16 +1004,12 @@
// Convert the object type
return OptionConverter.ConvertTypeTo(createdObject, typeConstraint);
}
- else
- {
- // The object is of the correct type
- return createdObject;
- }
+
+ // The object is of the correct type
+ return createdObject;
}
- #endregion Protected Instance Methods
-
- private bool HasCaseInsensitiveEnvironment
+ private static bool HasCaseInsensitiveEnvironment
{
get
{
@@ -1037,12 +1018,8 @@
}
}
- private IDictionary CreateCaseInsensitiveWrapper(IDictionary dict)
+ private static IDictionary CreateCaseInsensitiveWrapper(IDictionary dict)
{
- if (dict == null)
- {
- return dict;
- }
Hashtable hash = SystemInfo.CreateCaseInsensitiveHashtable();
foreach (DictionaryEntry entry in dict)
{
@@ -1051,8 +1028,6 @@
return hash;
}
- #region Private Constants
-
// String constants used while parsing the XML data
private const string CONFIGURATION_TAG = "log4net";
private const string RENDERER_TAG = "renderer";
@@ -1084,24 +1059,16 @@
// flag used on the level element
private const string INHERITED = "inherited";
- #endregion Private Constants
-
- #region Private Instance Fields
-
/// <summary>
/// key: appenderName, value: appender.
/// </summary>
- private Hashtable m_appenderBag;
+ private readonly Dictionary<string, IAppender> m_appenderBag = new(StringComparer.Ordinal);
/// <summary>
/// The Hierarchy being configured.
/// </summary>
private readonly Hierarchy m_hierarchy;
- #endregion Private Instance Fields
-
- #region Private Static Fields
-
/// <summary>
/// The fully qualified type of the XmlHierarchyConfigurator class.
/// </summary>
@@ -1110,7 +1077,5 @@
/// log message.
/// </remarks>
private static readonly Type declaringType = typeof(XmlHierarchyConfigurator);
-
- #endregion Private Static Fields
}
}
diff --git a/src/log4net/Repository/ILoggerRepository.cs b/src/log4net/Repository/ILoggerRepository.cs
index ac6638a..ad0b0d9 100644
--- a/src/log4net/Repository/ILoggerRepository.cs
+++ b/src/log4net/Repository/ILoggerRepository.cs
@@ -174,17 +174,17 @@
/// <summary>
/// Event to notify that the repository has been shut down.
/// </summary>
- event LoggerRepositoryShutdownEventHandler ShutdownEvent;
+ event LoggerRepositoryShutdownEventHandler? ShutdownEvent;
/// <summary>
/// Event to notify that the repository has had its configuration reset to default.
/// </summary>
- event LoggerRepositoryConfigurationResetEventHandler ConfigurationReset;
+ event LoggerRepositoryConfigurationResetEventHandler? ConfigurationReset;
/// <summary>
/// Event to notify that the repository's configuration has changed.
/// </summary>
- event LoggerRepositoryConfigurationChangedEventHandler ConfigurationChanged;
+ event LoggerRepositoryConfigurationChangedEventHandler? ConfigurationChanged;
/// <summary>
/// Repository specific properties.
diff --git a/src/log4net/Repository/LoggerRepositorySkeleton.cs b/src/log4net/Repository/LoggerRepositorySkeleton.cs
index 11afa00..ed04559 100644
--- a/src/log4net/Repository/LoggerRepositorySkeleton.cs
+++ b/src/log4net/Repository/LoggerRepositorySkeleton.cs
@@ -24,6 +24,7 @@
using log4net.Util;
using log4net.Plugin;
using System.Threading;
+using log4net.Appender;
namespace log4net.Repository
{
@@ -41,25 +42,12 @@
/// </remarks>
/// <author>Nicko Cadell</author>
/// <author>Gert Driesen</author>
- public abstract class LoggerRepositorySkeleton : ILoggerRepository, Appender.IFlushable
+ public abstract class LoggerRepositorySkeleton : ILoggerRepository, IFlushable
{
- #region Member Variables
-
- private string m_name;
- private RendererMap m_rendererMap;
- private PluginMap m_pluginMap;
- private LevelMap m_levelMap;
- private Level m_threshold;
- private bool m_configured;
- private ICollection m_configurationMessages;
- private event LoggerRepositoryShutdownEventHandler m_shutdownEvent;
- private event LoggerRepositoryConfigurationResetEventHandler m_configurationResetEvent;
- private event LoggerRepositoryConfigurationChangedEventHandler m_configurationChangedEvent;
- private PropertiesDictionary m_properties;
-
- #endregion
-
- #region Constructors
+ private readonly RendererMap m_rendererMap = new();
+ private readonly LevelMap m_levelMap = new();
+ private Level m_threshold = Level.All; // Don't disable any levels by default.
+ private ICollection m_configurationMessages = EmptyCollection.Instance;
/// <summary>
/// Default Constructor
@@ -84,23 +72,11 @@
/// </remarks>
protected LoggerRepositorySkeleton(PropertiesDictionary properties)
{
- m_properties = properties;
- m_rendererMap = new RendererMap();
- m_pluginMap = new PluginMap(this);
- m_levelMap = new LevelMap();
- m_configurationMessages = EmptyCollection.Instance;
- m_configured = false;
-
+ Properties = properties;
+ PluginMap = new PluginMap(this);
AddBuiltinLevels();
-
- // Don't disable any levels by default.
- m_threshold = Level.All;
}
- #endregion
-
- #region Implementation of ILoggerRepository
-
/// <summary>
/// The name of the repository
/// </summary>
@@ -114,11 +90,7 @@
/// stored by the <see cref="IRepositorySelector"/>.
/// </para>
/// </remarks>
- public virtual string Name
- {
- get { return m_name; }
- set { m_name = value; }
- }
+ public virtual string? Name { get; set; }
/// <summary>
/// The threshold for all events in this repository
@@ -133,10 +105,10 @@
/// </remarks>
public virtual Level Threshold
{
- get { return m_threshold; }
+ get => m_threshold;
set
{
- if (value != null)
+ if (value is not null)
{
m_threshold = value;
}
@@ -164,10 +136,7 @@
/// <see cref="IObjectRenderer"/> objects.
/// </para>
/// </remarks>
- public virtual RendererMap RendererMap
- {
- get { return m_rendererMap; }
- }
+ public virtual RendererMap RendererMap => m_rendererMap;
/// <summary>
/// The plugin map for this repository.
@@ -181,10 +150,7 @@
/// that have been attached to this repository.
/// </para>
/// </remarks>
- public virtual PluginMap PluginMap
- {
- get { return m_pluginMap; }
- }
+ public virtual PluginMap PluginMap { get; }
/// <summary>
/// Get the level map for the Repository.
@@ -199,10 +165,7 @@
/// this repository.
/// </para>
/// </remarks>
- public virtual LevelMap LevelMap
- {
- get { return m_levelMap; }
- }
+ public virtual LevelMap LevelMap => m_levelMap;
/// <summary>
/// Test if logger exists
@@ -328,20 +291,16 @@
/// Flag indicates if this repository has been configured.
/// </para>
/// </remarks>
- public virtual bool Configured
- {
- get { return m_configured; }
- set { m_configured = value; }
- }
+ public virtual bool Configured { get; set; }
/// <summary>
- /// Contains a list of internal messages captures during the
+ /// Contains a list of internal messages captured during the
/// last configuration.
/// </summary>
public virtual ICollection ConfigurationMessages
{
- get { return m_configurationMessages; }
- set { m_configurationMessages = value; }
+ get => m_configurationMessages;
+ set => m_configurationMessages = value;
}
/// <summary>
@@ -355,11 +314,7 @@
/// Event raised when the repository has been shutdown.
/// </para>
/// </remarks>
- public event LoggerRepositoryShutdownEventHandler ShutdownEvent
- {
- add { m_shutdownEvent += value; }
- remove { m_shutdownEvent -= value; }
- }
+ public event LoggerRepositoryShutdownEventHandler? ShutdownEvent;
/// <summary>
/// Event to notify that the repository has had its configuration reset.
@@ -373,11 +328,7 @@
/// reset to default.
/// </para>
/// </remarks>
- public event LoggerRepositoryConfigurationResetEventHandler ConfigurationReset
- {
- add { m_configurationResetEvent += value; }
- remove { m_configurationResetEvent -= value; }
- }
+ public event LoggerRepositoryConfigurationResetEventHandler? ConfigurationReset;
/// <summary>
/// Event to notify that the repository has had its configuration changed.
@@ -390,11 +341,7 @@
/// Event raised when the repository's configuration has been changed.
/// </para>
/// </remarks>
- public event LoggerRepositoryConfigurationChangedEventHandler ConfigurationChanged
- {
- add { m_configurationChangedEvent += value; }
- remove { m_configurationChangedEvent -= value; }
- }
+ public event LoggerRepositoryConfigurationChangedEventHandler? ConfigurationChanged;
/// <summary>
/// Repository specific properties
@@ -405,10 +352,7 @@
/// <remarks>
/// These properties can be specified on a repository specific basis
/// </remarks>
- public PropertiesDictionary Properties
- {
- get { return m_properties; }
- }
+ public PropertiesDictionary Properties { get; }
/// <summary>
/// Returns all the Appenders that are configured as an Array.
@@ -419,11 +363,7 @@
/// Returns all the Appenders that are configured as an Array.
/// </para>
/// </remarks>
- public abstract log4net.Appender.IAppender[] GetAppenders();
-
- #endregion
-
- #region Private Static Fields
+ public abstract IAppender[] GetAppenders();
/// <summary>
/// The fully qualified type of the LoggerRepositorySkeleton class.
@@ -434,8 +374,6 @@
/// </remarks>
private static readonly Type declaringType = typeof(LoggerRepositorySkeleton);
- #endregion Private Static Fields
-
private void AddBuiltinLevels()
{
// Add the predefined levels to the map
@@ -481,11 +419,11 @@
{
if (typeToRender == null)
{
- throw new ArgumentNullException("typeToRender");
+ throw new ArgumentNullException(nameof(typeToRender));
}
if (rendererInstance == null)
{
- throw new ArgumentNullException("rendererInstance");
+ throw new ArgumentNullException(nameof(rendererInstance));
}
m_rendererMap.Put(typeToRender, rendererInstance);
@@ -500,18 +438,10 @@
/// Notify any listeners that this repository is shutting down.
/// </para>
/// </remarks>
- protected virtual void OnShutdown(EventArgs e)
+ protected virtual void OnShutdown(EventArgs? e)
{
- if (e == null)
- {
- e = EventArgs.Empty;
- }
-
- LoggerRepositoryShutdownEventHandler handler = m_shutdownEvent;
- if (handler != null)
- {
- handler(this, e);
- }
+ e ??= EventArgs.Empty;
+ ShutdownEvent?.Invoke(this, e);
}
/// <summary>
@@ -523,18 +453,10 @@
/// Notify any listeners that this repository's configuration has been reset.
/// </para>
/// </remarks>
- protected virtual void OnConfigurationReset(EventArgs e)
+ protected virtual void OnConfigurationReset(EventArgs? e)
{
- if (e == null)
- {
- e = EventArgs.Empty;
- }
-
- LoggerRepositoryConfigurationResetEventHandler handler = m_configurationResetEvent;
- if (handler != null)
- {
- handler(this, e);
- }
+ e ??= EventArgs.Empty;
+ ConfigurationReset?.Invoke(this, e);
}
/// <summary>
@@ -546,18 +468,10 @@
/// Notify any listeners that this repository's configuration has changed.
/// </para>
/// </remarks>
- protected virtual void OnConfigurationChanged(EventArgs e)
+ protected virtual void OnConfigurationChanged(EventArgs? e)
{
- if (e == null)
- {
- e = EventArgs.Empty;
- }
-
- LoggerRepositoryConfigurationChangedEventHandler handler = m_configurationChangedEvent;
- if (handler != null)
- {
- handler(this, e);
- }
+ e ??= EventArgs.Empty;
+ ConfigurationChanged?.Invoke(this, e);
}
/// <summary>
@@ -589,12 +503,12 @@
/// <summary>
/// Flushes all configured Appenders that implement <see cref="log4net.Appender.IFlushable"/>.
/// </summary>
- /// <param name="millisecondsTimeout">The maximum time in milliseconds to wait for logging events from asycnhronous appenders to be flushed,
+ /// <param name="millisecondsTimeout">The maximum time in milliseconds to wait for logging events from asynchronous appenders to be flushed,
/// or <see cref="Timeout.Infinite"/> to wait indefinitely.</param>
/// <returns><c>True</c> if all logging events were flushed successfully, else <c>false</c>.</returns>
public bool Flush(int millisecondsTimeout)
{
- if (millisecondsTimeout < -1) throw new ArgumentOutOfRangeException("millisecondsTimeout", "Timeout must be -1 (Timeout.Infinite) or non-negative");
+ if (millisecondsTimeout < -1) throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout), "Timeout must be -1 (Timeout.Infinite) or non-negative");
// Assume success until one of the appenders fails
bool result = true;
@@ -603,11 +517,14 @@
DateTime startTimeUtc = DateTime.UtcNow;
// Do buffering appenders first. These may be forwarding to other appenders
- foreach (log4net.Appender.IAppender appender in GetAppenders())
+ foreach (IAppender appender in GetAppenders())
{
- log4net.Appender.IFlushable flushable = appender as log4net.Appender.IFlushable;
- if (flushable == null) continue;
- if (appender is Appender.BufferingAppenderSkeleton)
+ if (appender is not IFlushable flushable)
+ {
+ continue;
+ }
+
+ if (appender is BufferingAppenderSkeleton)
{
int timeout = GetWaitTime(startTimeUtc, millisecondsTimeout);
if (!flushable.Flush(timeout)) result = false;
@@ -615,11 +532,14 @@
}
// Do non-buffering appenders.
- foreach (log4net.Appender.IAppender appender in GetAppenders())
+ foreach (IAppender appender in GetAppenders())
{
- log4net.Appender.IFlushable flushable = appender as log4net.Appender.IFlushable;
- if (flushable == null) continue;
- if (!(appender is Appender.BufferingAppenderSkeleton))
+ if (appender is not IFlushable flushable)
+ {
+ continue;
+ }
+
+ if (appender is not BufferingAppenderSkeleton)
{
int timeout = GetWaitTime(startTimeUtc, millisecondsTimeout);
if (!flushable.Flush(timeout)) result = false;
diff --git a/src/log4net/ThreadContext.cs b/src/log4net/ThreadContext.cs
index e84dba5..6d17de1 100644
--- a/src/log4net/ThreadContext.cs
+++ b/src/log4net/ThreadContext.cs
@@ -17,9 +17,6 @@
//
#endregion
-using System;
-using System.Collections;
-
using log4net.Util;
namespace log4net
@@ -67,26 +64,8 @@
/// </example>
/// <threadsafety static="true" instance="true" />
/// <author>Nicko Cadell</author>
- public sealed class ThreadContext
+ public static class ThreadContext
{
- #region Private Instance Constructors
-
- /// <summary>
- /// Private Constructor.
- /// </summary>
- /// <remarks>
- /// <para>
- /// Uses a private access modifier to prevent instantiation of this class.
- /// </para>
- /// </remarks>
- private ThreadContext()
- {
- }
-
- #endregion Private Instance Constructors
-
- #region Public Static Properties
-
/// <summary>
/// The thread properties map
/// </summary>
@@ -99,10 +78,7 @@
/// properties with the same name.
/// </para>
/// </remarks>
- public static ThreadContextProperties Properties
- {
- get { return s_properties; }
- }
+ public static ThreadContextProperties Properties { get; } = new();
/// <summary>
/// The thread stacks
@@ -115,25 +91,6 @@
/// The thread local stacks.
/// </para>
/// </remarks>
- public static ThreadContextStacks Stacks
- {
- get { return s_stacks; }
- }
-
- #endregion Public Static Properties
-
- #region Private Static Fields
-
- /// <summary>
- /// The thread context properties instance
- /// </summary>
- private static readonly ThreadContextProperties s_properties = new ThreadContextProperties();
-
- /// <summary>
- /// The thread context stacks instance
- /// </summary>
- private static readonly ThreadContextStacks s_stacks = new ThreadContextStacks(s_properties);
-
- #endregion Private Static Fields
+ public static ThreadContextStacks Stacks { get; } = new(Properties);
}
}
diff --git a/src/log4net/Util/CompositeProperties.cs b/src/log4net/Util/CompositeProperties.cs
index 66ac7b7..5e1350f 100644
--- a/src/log4net/Util/CompositeProperties.cs
+++ b/src/log4net/Util/CompositeProperties.cs
@@ -17,8 +17,7 @@
//
#endregion
-using System;
-using System.Collections;
+using System.Collections.Generic;
namespace log4net.Util
{
@@ -34,14 +33,8 @@
/// <author>Nicko Cadell</author>
public sealed class CompositeProperties
{
- #region Private Instance Fields
-
- private PropertiesDictionary m_flattened = null;
- private ArrayList m_nestedProperties = new ArrayList();
-
- #endregion Private Instance Fields
-
- #region Public Instance Constructors
+ private PropertiesDictionary? m_flattened;
+ private readonly List<ReadOnlyPropertiesDictionary> m_nestedProperties = new();
/// <summary>
/// Constructor
@@ -55,10 +48,6 @@
{
}
- #endregion Public Instance Constructors
-
- #region Public Instance Properties
-
/// <summary>
/// Gets the value of a property
/// </summary>
@@ -78,12 +67,12 @@
/// <c>null</c> is returned.
/// </para>
/// </remarks>
- public object this[string key]
+ public object? this[string key]
{
get
{
// Look in the flattened properties first
- if (m_flattened != null)
+ if (m_flattened is not null)
{
return m_flattened[key];
}
@@ -91,19 +80,15 @@
// Look for the key in all the nested properties
foreach (ReadOnlyPropertiesDictionary cur in m_nestedProperties)
{
- if (cur.Contains(key))
+ if (cur.TryGetValue(key, out object? val))
{
- return cur[key];
+ return val;
}
}
return null;
}
}
- #endregion Public Instance Properties
-
- #region Public Instance Methods
-
/// <summary>
/// Add a Properties Dictionary to this composite collection
/// </summary>
@@ -132,24 +117,22 @@
/// </remarks>
public PropertiesDictionary Flatten()
{
- if (m_flattened == null)
+ if (m_flattened is null)
{
m_flattened = new PropertiesDictionary();
for (int i = m_nestedProperties.Count; --i >= 0;)
{
- ReadOnlyPropertiesDictionary cur = (ReadOnlyPropertiesDictionary)m_nestedProperties[i];
+ ReadOnlyPropertiesDictionary cur = m_nestedProperties[i];
- foreach (DictionaryEntry entry in cur)
+ foreach (KeyValuePair<string, object?> entry in cur)
{
- m_flattened[(string)entry.Key] = entry.Value;
+ m_flattened[entry.Key] = entry.Value;
}
}
}
return m_flattened;
}
-
- #endregion Public Instance Methods
}
}
diff --git a/src/log4net/Util/ContextPropertiesBase.cs b/src/log4net/Util/ContextPropertiesBase.cs
index 4727461..b75b0d0 100644
--- a/src/log4net/Util/ContextPropertiesBase.cs
+++ b/src/log4net/Util/ContextPropertiesBase.cs
@@ -17,34 +17,19 @@
//
#endregion
-using System;
-using System.Collections;
+#nullable enable
namespace log4net.Util
{
/// <summary>
/// Base class for Context Properties implementations
/// </summary>
- /// <remarks>
- /// <para>
- /// This class defines a basic property get set accessor
- /// </para>
- /// </remarks>
/// <author>Nicko Cadell</author>
public abstract class ContextPropertiesBase
{
/// <summary>
- /// Gets or sets the value of a property
+ /// Gets or sets the value of a property.
/// </summary>
- /// <value>
- /// The value for the property with the specified key
- /// </value>
- /// <remarks>
- /// <para>
- /// Gets or sets the value of a property
- /// </para>
- /// </remarks>
- public abstract object this[string key] { get; set; }
+ public abstract object? this[string key] { get; set; }
}
}
-
diff --git a/src/log4net/Util/GlobalContextProperties.cs b/src/log4net/Util/GlobalContextProperties.cs
index d516804..9d5c1ce 100644
--- a/src/log4net/Util/GlobalContextProperties.cs
+++ b/src/log4net/Util/GlobalContextProperties.cs
@@ -17,9 +17,6 @@
//
#endregion
-using System;
-using System.Collections;
-
namespace log4net.Util
{
/// <summary>
@@ -38,8 +35,6 @@
/// <author>Nicko Cadell</author>
public sealed class GlobalContextProperties : ContextPropertiesBase
{
- #region Private Instance Fields
-
/// <summary>
/// The read only copy of the properties.
/// </summary>
@@ -49,16 +44,12 @@
/// reordering reads and writes of this thread performed on different threads.
/// </para>
/// </remarks>
- private volatile ReadOnlyPropertiesDictionary m_readOnlyProperties = new ReadOnlyPropertiesDictionary();
+ private volatile ReadOnlyPropertiesDictionary m_readOnlyProperties = new();
/// <summary>
/// Lock object used to synchronize updates within this instance
/// </summary>
- private readonly object m_syncRoot = new object();
-
- #endregion Private Instance Fields
-
- #region Public Instance Constructors
+ private readonly object m_syncRoot = new();
/// <summary>
/// Constructor
@@ -72,10 +63,6 @@
{
}
- #endregion Public Instance Constructors
-
- #region Public Instance Properties
-
/// <summary>
/// Gets or sets the value of a property
/// </summary>
@@ -89,29 +76,22 @@
/// the properties is created.
/// </para>
/// </remarks>
- public override object this[string key]
+ public override object? this[string key]
{
- get
- {
- return m_readOnlyProperties[key];
- }
+ get => m_readOnlyProperties[key];
set
{
lock (m_syncRoot)
{
- PropertiesDictionary mutableProps = new PropertiesDictionary(m_readOnlyProperties);
-
- mutableProps[key] = value;
-
+ var mutableProps = new PropertiesDictionary(m_readOnlyProperties)
+ {
+ [key] = value
+ };
m_readOnlyProperties = new ReadOnlyPropertiesDictionary(mutableProps);
}
}
}
- #endregion Public Instance Properties
-
- #region Public Instance Methods
-
/// <summary>
/// Remove a property from the global context
/// </summary>
@@ -128,10 +108,8 @@
{
if (m_readOnlyProperties.Contains(key))
{
- PropertiesDictionary mutableProps = new PropertiesDictionary(m_readOnlyProperties);
-
+ var mutableProps = new PropertiesDictionary(m_readOnlyProperties);
mutableProps.Remove(key);
-
m_readOnlyProperties = new ReadOnlyPropertiesDictionary(mutableProps);
}
}
@@ -148,10 +126,6 @@
}
}
- #endregion Public Instance Methods
-
- #region Internal Instance Methods
-
/// <summary>
/// Get a readonly immutable copy of the properties
/// </summary>
@@ -166,8 +140,5 @@
{
return m_readOnlyProperties;
}
-
- #endregion Internal Instance Methods
}
}
-
diff --git a/src/log4net/Util/LogLog.cs b/src/log4net/Util/LogLog.cs
index 6a1d79e..4ce84aa 100644
--- a/src/log4net/Util/LogLog.cs
+++ b/src/log4net/Util/LogLog.cs
@@ -19,6 +19,7 @@
using System;
using System.Collections;
+using System.Collections.Generic;
using System.Diagnostics;
namespace log4net.Util
@@ -28,7 +29,7 @@
/// </summary>
/// <param name="source"></param>
/// <param name="e"></param>
- public delegate void LogReceivedEventHandler(object source, LogReceivedEventArgs e);
+ public delegate void LogReceivedEventHandler(object? source, LogReceivedEventArgs e);
/// <summary>
/// Outputs log statements from within the log4net assembly.
@@ -52,37 +53,22 @@
/// <summary>
/// The event raised when an internal message has been received.
/// </summary>
- public static event LogReceivedEventHandler LogReceived;
-
- private readonly Type source;
- private readonly DateTime timeStampUtc;
- private readonly string prefix;
- private readonly string message;
- private readonly Exception exception;
+ public static event LogReceivedEventHandler? LogReceived;
/// <summary>
/// The Type that generated the internal message.
/// </summary>
- public Type Source
- {
- get { return source; }
- }
+ public Type Source { get; }
/// <summary>
/// The DateTime stamp of when the internal message was received.
/// </summary>
- public DateTime TimeStamp
- {
- get { return timeStampUtc.ToLocalTime(); }
- }
+ public DateTime TimeStamp => TimeStampUtc.ToLocalTime();
/// <summary>
/// The UTC DateTime stamp of when the internal message was received.
/// </summary>
- public DateTime TimeStampUtc
- {
- get { return timeStampUtc; }
- }
+ public DateTime TimeStampUtc { get; }
/// <summary>
/// A string indicating the severity of the internal message.
@@ -92,18 +78,12 @@
/// "log4net:ERROR ",
/// "log4net:WARN "
/// </remarks>
- public string Prefix
- {
- get { return prefix; }
- }
+ public string Prefix { get; }
/// <summary>
/// The internal log message.
/// </summary>
- public string Message
- {
- get { return message; }
- }
+ public string Message { get; }
/// <summary>
/// The Exception related to the message.
@@ -111,10 +91,7 @@
/// <remarks>
/// Optional. Will be null if no Exception was passed.
/// </remarks>
- public Exception Exception
- {
- get { return exception; }
- }
+ public Exception? Exception { get; }
/// <summary>
/// Formats Prefix, Source, and Message in the same format as the value
@@ -126,29 +103,19 @@
return Prefix + Source.Name + ": " + Message;
}
- #region Private Instance Constructors
-
/// <summary>
/// Initializes a new instance of the <see cref="LogLog" /> class.
/// </summary>
- /// <param name="source"></param>
- /// <param name="prefix"></param>
- /// <param name="message"></param>
- /// <param name="exception"></param>
- public LogLog(Type source, string prefix, string message, Exception exception)
+ public LogLog(Type source, string prefix, string message, Exception? exception)
{
- timeStampUtc = DateTime.UtcNow;
+ TimeStampUtc = DateTime.UtcNow;
- this.source = source;
- this.prefix = prefix;
- this.message = message;
- this.exception = exception;
+ Source = source;
+ Prefix = prefix;
+ Message = message;
+ Exception = exception;
}
- #endregion Private Instance Constructors
-
- #region Static Constructor
-
/// <summary>
/// Static constructor that initializes logging by reading
/// settings from the application configuration file.
@@ -184,10 +151,6 @@
}
}
- #endregion Static Constructor
-
- #region Public Static Properties
-
/// <summary>
/// Gets or sets a value indicating whether log4net internal logging
/// is enabled or disabled.
@@ -224,11 +187,7 @@
/// </configuration>
/// </code>
/// </example>
- public static bool InternalDebugging
- {
- get { return s_debugEnabled; }
- set { s_debugEnabled = value; }
- }
+ public static bool InternalDebugging { get; set; }
/// <summary>
/// Gets or sets a value indicating whether log4net should generate no output
@@ -264,24 +223,12 @@
/// </configuration>
/// </code>
/// </example>
- public static bool QuietMode
- {
- get { return s_quietMode; }
- set { s_quietMode = value; }
- }
+ public static bool QuietMode { get; set; }
/// <summary>
///
/// </summary>
- public static bool EmitInternalMessages
- {
- get { return s_emitInternalMessages; }
- set { s_emitInternalMessages = value; }
- }
-
- #endregion Public Static Properties
-
- #region Public Static Methods
+ public static bool EmitInternalMessages { get; set; } = true;
/// <summary>
/// Raises the LogReceived event when an internal messages is received.
@@ -290,12 +237,9 @@
/// <param name="prefix"></param>
/// <param name="message"></param>
/// <param name="exception"></param>
- public static void OnLogReceived(Type source, string prefix, string message, Exception exception)
+ public static void OnLogReceived(Type source, string prefix, string message, Exception? exception)
{
- if (LogReceived != null)
- {
- LogReceived(null, new LogReceivedEventArgs(new LogLog(source, prefix, message, exception)));
- }
+ LogReceived?.Invoke(null, new LogReceivedEventArgs(new LogLog(source, prefix, message, exception)));
}
/// <summary>
@@ -309,10 +253,7 @@
/// Test if LogLog.Debug is enabled for output.
/// </para>
/// </remarks>
- public static bool IsDebugEnabled
- {
- get { return s_debugEnabled && !s_quietMode; }
- }
+ public static bool IsDebugEnabled => InternalDebugging && !QuietMode;
/// <summary>
/// Writes log4net internal debug messages to the
@@ -352,7 +293,7 @@
/// the string "log4net: ".
/// </para>
/// </remarks>
- public static void Debug(Type source, string message, Exception exception)
+ public static void Debug(Type source, string message, Exception? exception)
{
if (IsDebugEnabled)
{
@@ -375,15 +316,7 @@
/// <value>
/// <c>true</c> if Warn is enabled
/// </value>
- /// <remarks>
- /// <para>
- /// Test if LogLog.Warn is enabled for output.
- /// </para>
- /// </remarks>
- public static bool IsWarnEnabled
- {
- get { return !s_quietMode; }
- }
+ public static bool IsWarnEnabled => !QuietMode;
/// <summary>
/// Writes log4net internal warning messages to the
@@ -423,7 +356,7 @@
/// the string "log4net:WARN ".
/// </para>
/// </remarks>
- public static void Warn(Type source, string message, Exception exception)
+ public static void Warn(Type source, string message, Exception? exception)
{
if (IsWarnEnabled)
{
@@ -451,10 +384,7 @@
/// Test if LogLog.Error is enabled for output.
/// </para>
/// </remarks>
- public static bool IsErrorEnabled
- {
- get { return !s_quietMode; }
- }
+ public static bool IsErrorEnabled => !QuietMode;
/// <summary>
/// Writes log4net internal error messages to the
@@ -494,7 +424,7 @@
/// the string "log4net:ERROR ".
/// </para>
/// </remarks>
- public static void Error(Type source, string message, Exception exception)
+ public static void Error(Type source, string message, Exception? exception)
{
if (IsErrorEnabled)
{
@@ -511,8 +441,6 @@
}
}
- #endregion Public Static Methods
-
/// <summary>
/// Writes output to the standard output stream.
/// </summary>
@@ -520,8 +448,6 @@
/// <remarks>
/// <para>
/// Writes to both Console.Out and System.Diagnostics.Trace.
- /// Note that the System.Diagnostics.Trace is not supported
- /// on the Compact Framework.
/// </para>
/// <para>
/// If the AppDomain is not configured with a config file then
@@ -571,67 +497,45 @@
}
}
- #region Private Static Fields
-
- /// <summary>
- /// Default debug level
- /// </summary>
- private static bool s_debugEnabled = false;
-
- /// <summary>
- /// In quietMode not even errors generate any output.
- /// </summary>
- private static bool s_quietMode = false;
-
- private static bool s_emitInternalMessages = true;
-
private const string PREFIX = "log4net: ";
private const string ERR_PREFIX = "log4net:ERROR ";
private const string WARN_PREFIX = "log4net:WARN ";
- #endregion Private Static Fields
-
/// <summary>
/// Subscribes to the LogLog.LogReceived event and stores messages
/// to the supplied IList instance.
/// </summary>
public class LogReceivedAdapter : IDisposable
{
- private readonly IList items;
- private readonly LogReceivedEventHandler handler;
+ private readonly LogReceivedEventHandler m_handler;
/// <summary>
///
/// </summary>
/// <param name="items"></param>
- public LogReceivedAdapter(IList items)
+ public LogReceivedAdapter(List<LogLog> items)
{
- this.items = items;
-
- handler = new LogReceivedEventHandler(LogLog_LogReceived);
-
- LogReceived += handler;
+ Items = items;
+ m_handler = LogLog_LogReceived;
+ LogReceived += m_handler;
}
void LogLog_LogReceived(object source, LogReceivedEventArgs e)
{
- items.Add(e.LogLog);
+ Items.Add(e.LogLog);
}
/// <summary>
///
/// </summary>
- public IList Items
- {
- get { return items; }
- }
+ public List<LogLog> Items { get; }
/// <summary>
///
/// </summary>
public void Dispose()
{
- LogReceived -= handler;
+ LogReceived -= m_handler;
}
}
}
@@ -641,23 +545,18 @@
/// </summary>
public class LogReceivedEventArgs : EventArgs
{
- private readonly LogLog loglog;
-
/// <summary>
///
/// </summary>
/// <param name="loglog"></param>
public LogReceivedEventArgs(LogLog loglog)
{
- this.loglog = loglog;
+ this.LogLog = loglog;
}
/// <summary>
///
/// </summary>
- public LogLog LogLog
- {
- get { return loglog; }
- }
+ public LogLog LogLog { get; }
}
}
diff --git a/src/log4net/Util/LogicalThreadContextProperties.cs b/src/log4net/Util/LogicalThreadContextProperties.cs
index 28020c5..f42a6d2 100644
--- a/src/log4net/Util/LogicalThreadContextProperties.cs
+++ b/src/log4net/Util/LogicalThreadContextProperties.cs
@@ -26,6 +26,8 @@
using CallContext = System.Threading.AsyncLocal<log4net.Util.PropertiesDictionary>;
#endif
+#nullable enable
+
namespace log4net.Util
{
/// <summary>
@@ -64,9 +66,7 @@
/// <summary>
/// Flag used to disable this context if we don't have permission to access the CallContext.
/// </summary>
- private bool m_disabled = false;
-
- #region Public Instance Constructors
+ private bool m_disabled;
/// <summary>
/// Constructor
@@ -80,49 +80,27 @@
{
}
- #endregion Public Instance Constructors
-
- #region Public Instance Properties
-
- /// <summary>
- /// Gets or sets the value of a property
- /// </summary>
- /// <value>
- /// The value for the property with the specified key
- /// </value>
- /// <remarks>
- /// <para>
- /// Get or set the property value for the <paramref name="key"/> specified.
- /// </para>
- /// </remarks>
- public override object this[string key]
+ /// <inheritdoc/>
+ public override object? this[string key]
{
get
{
// Don't create the dictionary if it does not already exist
- PropertiesDictionary dictionary = GetProperties(false);
- if (dictionary != null)
- {
- return dictionary[key];
- }
- return null;
+ PropertiesDictionary? dictionary = GetProperties(false);
+ return dictionary?[key];
}
set
{
// Force the dictionary to be created
- PropertiesDictionary props = GetProperties(true);
+ PropertiesDictionary props = GetProperties(true)!;
// Reason for cloning the dictionary below: object instances set on the CallContext
// need to be immutable to correctly flow through async/await
- PropertiesDictionary immutableProps = new PropertiesDictionary(props);
+ var immutableProps = new PropertiesDictionary(props);
immutableProps[key] = value;
SetLogicalProperties(immutableProps);
}
}
- #endregion Public Instance Properties
-
- #region Public Instance Methods
-
/// <summary>
/// Remove a property
/// </summary>
@@ -134,7 +112,7 @@
/// </remarks>
public void Remove(string key)
{
- PropertiesDictionary dictionary = GetProperties(false);
+ PropertiesDictionary? dictionary = GetProperties(false);
if (dictionary != null)
{
PropertiesDictionary immutableProps = new PropertiesDictionary(dictionary);
@@ -153,22 +131,17 @@
/// </remarks>
public void Clear()
{
- PropertiesDictionary dictionary = GetProperties(false);
- if (dictionary != null)
+ PropertiesDictionary? dictionary = GetProperties(false);
+ if (dictionary is not null)
{
- PropertiesDictionary immutableProps = new PropertiesDictionary();
- SetLogicalProperties(immutableProps);
+ SetLogicalProperties(new PropertiesDictionary());
}
}
- #endregion Public Instance Methods
-
- #region Internal Instance Methods
-
/// <summary>
/// Get the PropertiesDictionary stored in the LocalDataStoreSlot for this thread.
/// </summary>
- /// <param name="create">create the dictionary if it does not exist, otherwise return null if is does not exist</param>
+ /// <param name="create">create the dictionary if it does not exist, otherwise return null if it does not exist</param>
/// <returns>the properties for this thread</returns>
/// <remarks>
/// <para>
@@ -177,13 +150,13 @@
/// caller must clone the collection before doings so.
/// </para>
/// </remarks>
- internal PropertiesDictionary GetProperties(bool create)
+ internal PropertiesDictionary? GetProperties(bool create)
{
if (!m_disabled)
{
try
{
- PropertiesDictionary properties = GetLogicalProperties();
+ PropertiesDictionary? properties = GetLogicalProperties();
if (properties == null && create)
{
properties = new PropertiesDictionary();
@@ -208,20 +181,16 @@
return null;
}
- #endregion Internal Instance Methods
-
- #region Private Static Methods
-
/// <summary>
/// Gets the call context get data.
/// </summary>
- /// <returns>The peroperties dictionary stored in the call context</returns>
+ /// <returns>The properties dictionary stored in the call context</returns>
/// <remarks>
/// The <see cref="CallContext"/> method GetData security link demand, therefore we must
- /// put the method call in a seperate method that we can wrap in an exception handler.
+ /// put the method call in a separate method that we can wrap in an exception handler.
/// </remarks>
- [System.Security.SecuritySafeCritical]
- private static PropertiesDictionary GetLogicalProperties()
+ [SecuritySafeCritical]
+ private static PropertiesDictionary? GetLogicalProperties()
{
#if NETSTANDARD2_0_OR_GREATER
return AsyncLocalDictionary.Value;
@@ -236,9 +205,9 @@
/// <param name="properties">The properties.</param>
/// <remarks>
/// The <see cref="CallContext"/> method SetData has a security link demand, therefore we must
- /// put the method call in a seperate method that we can wrap in an exception handler.
+ /// put the method call in a separate method that we can wrap in an exception handler.
/// </remarks>
- [System.Security.SecuritySafeCritical]
+ [SecuritySafeCritical]
private static void SetLogicalProperties(PropertiesDictionary properties)
{
#if NETSTANDARD2_0_OR_GREATER
@@ -248,10 +217,6 @@
#endif
}
- #endregion
-
- #region Private Static Fields
-
/// <summary>
/// The fully qualified type of the LogicalThreadContextProperties class.
/// </summary>
@@ -260,7 +225,5 @@
/// log message.
/// </remarks>
private static readonly Type declaringType = typeof(LogicalThreadContextProperties);
-
- #endregion Private Static Fields
}
}
\ No newline at end of file
diff --git a/src/log4net/Util/LogicalThreadContextStack.cs b/src/log4net/Util/LogicalThreadContextStack.cs
index 6a92248..fd407e3 100644
--- a/src/log4net/Util/LogicalThreadContextStack.cs
+++ b/src/log4net/Util/LogicalThreadContextStack.cs
@@ -18,13 +18,13 @@
#endregion
using System;
-using System.Collections;
-
+using System.Collections.Generic;
using log4net.Core;
+#nullable enable
+
namespace log4net.Util
{
-
/// <summary>
/// Delegate type used for LogicalThreadContextStack's callbacks.
/// </summary>
@@ -33,36 +33,25 @@
/// <summary>
/// Implementation of Stack for the <see cref="log4net.LogicalThreadContext"/>
/// </summary>
- /// <remarks>
- /// <para>
- /// Implementation of Stack for the <see cref="log4net.LogicalThreadContext"/>
- /// </para>
- /// </remarks>
/// <author>Nicko Cadell</author>
public sealed class LogicalThreadContextStack : IFixingRequired
{
- #region Private Instance Fields
-
/// <summary>
/// The stack store.
/// </summary>
- private Stack m_stack = new Stack();
+ private Stack<StackFrame> m_stack = new();
/// <summary>
/// The name of this <see cref="log4net.Util.LogicalThreadContextStack"/> within the
/// <see cref="log4net.Util.LogicalThreadContextProperties"/>.
/// </summary>
- private string m_propertyKey;
+ private readonly string m_propertyKey;
/// <summary>
/// The callback used to let the <see cref="log4net.Util.LogicalThreadContextStacks"/> register a
/// new instance of a <see cref="log4net.Util.LogicalThreadContextStack"/>.
/// </summary>
- private TwoArgAction<string, LogicalThreadContextStack> m_registerNew;
-
- #endregion Private Instance Fields
-
- #region Public Instance Constructors
+ private readonly TwoArgAction<string, LogicalThreadContextStack> m_registerNew;
/// <summary>
/// Internal constructor
@@ -78,16 +67,9 @@
m_registerNew = registerNew;
}
- #endregion Public Instance Constructors
-
- #region Public Properties
-
/// <summary>
- /// The number of messages in the stack
+ /// Gets the number of messages in the stack.
/// </summary>
- /// <value>
- /// The current number of messages in the stack
- /// </value>
/// <remarks>
/// <para>
/// The current number of messages in the stack. That is
@@ -95,14 +77,7 @@
/// minus the number of times <see cref="Pop"/> has been called.
/// </para>
/// </remarks>
- public int Count
- {
- get { return m_stack.Count; }
- }
-
- #endregion // Public Properties
-
- #region Public Methods
+ public int Count => m_stack.Count;
/// <summary>
/// Clears all the contextual information held in this stack.
@@ -135,17 +110,16 @@
/// empty string (not <see langword="null"/>) is returned.
/// </para>
/// </remarks>
- public string Pop()
+ public string? Pop()
{
// copy current stack
- Stack stack = new Stack(new Stack(m_stack));
- string result = "";
+ var stack = new Stack<StackFrame>(new Stack<StackFrame>(m_stack));
+ string? result = string.Empty;
if (stack.Count > 0)
{
- result = ((StackFrame)(stack.Pop())).Message;
+ result = stack.Pop().Message;
}
- LogicalThreadContextStack ltcs = new LogicalThreadContextStack(m_propertyKey, m_registerNew);
- ltcs.m_stack = stack;
+ var ltcs = new LogicalThreadContextStack(m_propertyKey, m_registerNew) { m_stack = stack };
m_registerNew(m_propertyKey, ltcs);
return result;
}
@@ -173,11 +147,11 @@
/// }
/// </code>
/// </example>
- public IDisposable Push(string message)
+ public IDisposable Push(string? message)
{
// do modifications on a copy
- Stack stack = new Stack(new Stack(m_stack));
- stack.Push(new StackFrame(message, (stack.Count > 0) ? (StackFrame)stack.Peek() : null));
+ var stack = new Stack<StackFrame>(new Stack<StackFrame>(m_stack));
+ stack.Push(new StackFrame(message, (stack.Count > 0) ? stack.Peek() : null));
LogicalThreadContextStack contextStack = new LogicalThreadContextStack(m_propertyKey, m_registerNew);
contextStack.m_stack = stack;
@@ -195,54 +169,31 @@
/// empty string (not <see langword="null"/>) is returned.
/// </para>
/// </remarks>
- public string Peek()
+ public string? Peek()
{
- Stack stack = m_stack;
+ Stack<StackFrame> stack = m_stack;
if (stack.Count > 0)
{
- return ((StackFrame)stack.Peek()).Message;
+ return stack.Peek().Message;
}
- return "";
+ return string.Empty;
}
- #endregion Public Methods
-
- #region Internal Methods
-
/// <summary>
/// Gets the current context information for this stack.
/// </summary>
/// <returns>The current context information.</returns>
- internal string GetFullMessage()
+ internal string? GetFullMessage()
{
- Stack stack = m_stack;
+ Stack<StackFrame> stack = m_stack;
if (stack.Count > 0)
{
- return ((StackFrame)(stack.Peek())).FullMessage;
+ return stack.Peek().FullMessage;
}
return null;
}
/// <summary>
- /// Gets and sets the internal stack used by this <see cref="LogicalThreadContextStack"/>
- /// </summary>
- /// <value>The internal storage stack</value>
- /// <remarks>
- /// <para>
- /// This property is provided only to support backward compatability
- /// of the <see cref="NDC"/>. Tytpically the internal stack should not
- /// be modified.
- /// </para>
- /// </remarks>
- internal Stack InternalStack
- {
- get { return m_stack; }
- set { m_stack = value; }
- }
-
- #endregion Internal Methods
-
- /// <summary>
/// Gets the current context information for this stack.
/// </summary>
/// <returns>Gets the current context information</returns>
@@ -251,44 +202,23 @@
/// Gets the current context information for this stack.
/// </para>
/// </remarks>
- public override string ToString()
+ public override string? ToString()
{
return GetFullMessage();
}
/// <summary>
- /// Get a portable version of this object
+ /// Gets a cross-thread portable version of this object
/// </summary>
- /// <returns>the portable instance of this object</returns>
- /// <remarks>
- /// <para>
- /// Get a cross thread portable version of this object
- /// </para>
- /// </remarks>
- object IFixingRequired.GetFixedObject()
- {
- return GetFullMessage();
- }
+ object? IFixingRequired.GetFixedObject() => GetFullMessage();
/// <summary>
/// Inner class used to represent a single context frame in the stack.
/// </summary>
- /// <remarks>
- /// <para>
- /// Inner class used to represent a single context frame in the stack.
- /// </para>
- /// </remarks>
- private sealed class StackFrame
+ internal sealed class StackFrame
{
- #region Private Instance Fields
-
- private readonly string m_message;
- private readonly StackFrame m_parent;
- private string m_fullMessage = null;
-
- #endregion
-
- #region Internal Instance Constructors
+ private readonly StackFrame? m_parent;
+ private string? m_fullMessage;
/// <summary>
/// Constructor
@@ -301,9 +231,9 @@
/// with the specified message and parent context.
/// </para>
/// </remarks>
- internal StackFrame(string message, StackFrame parent)
+ internal StackFrame(string? message, StackFrame? parent)
{
- m_message = message;
+ Message = message;
m_parent = parent;
if (parent == null)
@@ -312,10 +242,6 @@
}
}
- #endregion Internal Instance Constructors
-
- #region Internal Instance Properties
-
/// <summary>
/// Get the message.
/// </summary>
@@ -325,10 +251,7 @@
/// Get the message.
/// </para>
/// </remarks>
- internal string Message
- {
- get { return m_message; }
- }
+ internal string? Message { get; }
/// <summary>
/// Gets the full text of the context down to the root level.
@@ -341,19 +264,18 @@
/// Gets the full text of the context down to the root level.
/// </para>
/// </remarks>
- internal string FullMessage
+ internal string? FullMessage
{
get
{
if (m_fullMessage == null && m_parent != null)
{
- m_fullMessage = string.Concat(m_parent.FullMessage, " ", m_message);
+ m_fullMessage = string.Concat(m_parent.FullMessage, " ", Message);
}
+
return m_fullMessage;
}
}
-
- #endregion Internal Instance Properties
}
/// <summary>
@@ -365,23 +287,17 @@
/// with the <see langword="using"/> pattern to remove the stack frame at the end of the scope.
/// </para>
/// </remarks>
- private struct AutoPopStackFrame : IDisposable
+ private readonly struct AutoPopStackFrame : IDisposable
{
- #region Private Instance Fields
-
/// <summary>
/// The depth to trim the stack to when this instance is disposed
/// </summary>
- private int m_frameDepth;
+ private readonly int m_frameDepth;
/// <summary>
/// The outer LogicalThreadContextStack.
/// </summary>
- private LogicalThreadContextStack m_logicalThreadContextStack;
-
- #endregion Private Instance Fields
-
- #region Internal Instance Constructors
+ private readonly LogicalThreadContextStack m_logicalThreadContextStack;
/// <summary>
/// Constructor
@@ -400,10 +316,6 @@
m_logicalThreadContextStack = logicalThreadContextStack;
}
- #endregion Internal Instance Constructors
-
- #region Implementation of IDisposable
-
/// <summary>
/// Returns the stack to the correct depth.
/// </summary>
@@ -414,22 +326,20 @@
/// </remarks>
public void Dispose()
{
- if (m_frameDepth >= 0 && m_logicalThreadContextStack.m_stack != null)
+ if (m_frameDepth >= 0)
{
- Stack stack = new Stack(new Stack(m_logicalThreadContextStack.m_stack));
+ var stack = new Stack<StackFrame>(new Stack<StackFrame>(m_logicalThreadContextStack.m_stack));
while (stack.Count > m_frameDepth)
{
stack.Pop();
}
- LogicalThreadContextStack ltcs = new LogicalThreadContextStack(m_logicalThreadContextStack.m_propertyKey, m_logicalThreadContextStack.m_registerNew);
- ltcs.m_stack = stack;
- m_logicalThreadContextStack.m_registerNew(m_logicalThreadContextStack.m_propertyKey,
- ltcs);
+ var ltcs = new LogicalThreadContextStack(m_logicalThreadContextStack.m_propertyKey, m_logicalThreadContextStack.m_registerNew)
+ {
+ m_stack = stack
+ };
+ m_logicalThreadContextStack.m_registerNew(m_logicalThreadContextStack.m_propertyKey, ltcs);
}
}
-
- #endregion Implementation of IDisposable
}
-
}
-}
\ No newline at end of file
+}
diff --git a/src/log4net/Util/LogicalThreadContextStacks.cs b/src/log4net/Util/LogicalThreadContextStacks.cs
index 0d32d80..f797f48 100644
--- a/src/log4net/Util/LogicalThreadContextStacks.cs
+++ b/src/log4net/Util/LogicalThreadContextStacks.cs
@@ -24,18 +24,11 @@
/// <summary>
/// Implementation of Stacks collection for the <see cref="log4net.LogicalThreadContext"/>
/// </summary>
- /// <remarks>
- /// <para>
- /// Implementation of Stacks collection for the <see cref="log4net.LogicalThreadContext"/>
- /// </para>
- /// </remarks>
/// <author>Nicko Cadell</author>
public sealed class LogicalThreadContextStacks
{
private readonly LogicalThreadContextProperties m_properties;
- #region Public Instance Constructors
-
/// <summary>
/// Internal constructor
/// </summary>
@@ -49,10 +42,6 @@
m_properties = properties;
}
- #endregion Public Instance Constructors
-
- #region Public Instance Properties
-
/// <summary>
/// Gets the named thread context stack
/// </summary>
@@ -74,7 +63,7 @@
if (propertyValue == null)
{
// Stack does not exist, create
- stack = new LogicalThreadContextStack(key, registerNew);
+ stack = new LogicalThreadContextStack(key, RegisterNew);
m_properties[key] = stack;
}
else
@@ -96,7 +85,7 @@
LogLog.Error(declaringType, "ThreadContextStacks: Request for stack named [" + key + "] failed because a property with the same name exists which is a [" + propertyValue.GetType().Name + "] with value [" + propertyValueString + "]");
- stack = new LogicalThreadContextStack(key, registerNew);
+ stack = new LogicalThreadContextStack(key, RegisterNew);
}
}
@@ -104,19 +93,11 @@
}
}
- #endregion Public Instance Properties
-
- #region Private Instance Fields
-
- private void registerNew(string stackName, LogicalThreadContextStack stack)
+ private void RegisterNew(string stackName, LogicalThreadContextStack stack)
{
m_properties[stackName] = stack;
}
- #endregion Private Instance Fields
-
- #region Private Static Fields
-
/// <summary>
/// The fully qualified type of the ThreadContextStacks class.
/// </summary>
@@ -125,7 +106,5 @@
/// log message.
/// </remarks>
private static readonly Type declaringType = typeof(LogicalThreadContextStacks);
-
- #endregion Private Static Fields
}
}
\ No newline at end of file
diff --git a/src/log4net/Util/OptionConverter.cs b/src/log4net/Util/OptionConverter.cs
index 8171213..8e5033e 100644
--- a/src/log4net/Util/OptionConverter.cs
+++ b/src/log4net/Util/OptionConverter.cs
@@ -25,6 +25,8 @@
using log4net.Core;
using log4net.Util.TypeConverters;
+#nullable enable
+
namespace log4net.Util
{
/// <summary>
@@ -37,26 +39,8 @@
/// </remarks>
/// <author>Nicko Cadell</author>
/// <author>Gert Driesen</author>
- public sealed class OptionConverter
+ public static class OptionConverter
{
- #region Private Instance Constructors
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OptionConverter" /> class.
- /// </summary>
- /// <remarks>
- /// <para>
- /// Uses a private access modifier to prevent instantiation of this class.
- /// </para>
- /// </remarks>
- private OptionConverter()
- {
- }
-
- #endregion Private Instance Constructors
-
- #region Public Static Methods
-
/// <summary>
/// Converts a string to a <see cref="bool" /> value.
/// </summary>
@@ -70,9 +54,9 @@
/// Otherwise, <paramref name="defaultValue"/> is returned.
/// </para>
/// </remarks>
- public static bool ToBoolean(string argValue, bool defaultValue)
+ public static bool ToBoolean(string? argValue, bool defaultValue)
{
- if (argValue != null && argValue.Length > 0)
+ if (!string.IsNullOrEmpty(argValue))
{
try
{
@@ -80,7 +64,7 @@
}
catch (Exception e)
{
- LogLog.Error(declaringType, "[" + argValue + "] is not in proper bool form.", e);
+ LogLog.Error(declaringType, $"[{argValue}] is not in proper bool form.", e);
}
}
return defaultValue;
@@ -102,9 +86,9 @@
/// cannot be converted to a <see cref="long" /> value.
/// </para>
/// </remarks>
- public static long ToFileSize(string argValue, long defaultValue)
+ public static long ToFileSize(string? argValue, long defaultValue)
{
- if (argValue == null)
+ if (argValue is null)
{
return defaultValue;
}
@@ -113,35 +97,32 @@
long multiplier = 1;
int index;
- if ((index = s.IndexOf("KB")) != -1)
+ if ((index = s.IndexOf("KB", StringComparison.Ordinal)) != -1)
{
multiplier = 1024;
s = s.Substring(0, index);
}
- else if ((index = s.IndexOf("MB")) != -1)
+ else if ((index = s.IndexOf("MB", StringComparison.Ordinal)) != -1)
{
multiplier = 1024 * 1024;
s = s.Substring(0, index);
}
- else if ((index = s.IndexOf("GB")) != -1)
+ else if ((index = s.IndexOf("GB", StringComparison.Ordinal)) != -1)
{
multiplier = 1024 * 1024 * 1024;
s = s.Substring(0, index);
}
- if (s != null)
- {
- // Try again to remove whitespace between the number and the size specifier
- s = s.Trim();
- long longVal;
- if (SystemInfo.TryParse(s, out longVal))
- {
- return longVal * multiplier;
- }
- else
- {
- LogLog.Error(declaringType, "OptionConverter: [" + s + "] is not in the correct file size syntax.");
- }
+ // Try again to remove whitespace between the number and the size specifier
+ s = s.Trim();
+
+ if (SystemInfo.TryParse(s, out long longVal))
+ {
+ return longVal * multiplier;
+ }
+ else
+ {
+ LogLog.Error(declaringType, $"OptionConverter: [{s}] is not in the correct file size syntax.");
}
return defaultValue;
}
@@ -161,11 +142,11 @@
/// to convert the string value into the specified target type.
/// </para>
/// </remarks>
- public static object ConvertStringTo(Type target, string txt)
+ public static object? ConvertStringTo(Type target, string txt)
{
- if (target == null)
+ if (target is null)
{
- throw new ArgumentNullException("target");
+ throw new ArgumentNullException(nameof(target));
}
// If we want a string we already have the correct type
@@ -175,8 +156,8 @@
}
// First lets try to find a type converter
- IConvertFrom typeConverter = ConverterRegistry.GetConvertFrom(target);
- if (typeConverter != null && typeConverter.CanConvertFrom(typeof(string)))
+ IConvertFrom? typeConverter = ConverterRegistry.GetConvertFrom(target);
+ if (typeConverter is not null && typeConverter.CanConvertFrom(typeof(string)))
{
// Found appropriate converter
return typeConverter.ConvertFrom(txt);
@@ -196,8 +177,7 @@
// to an arbitrary type T there will be a static method defined on type T called Parse
// that will take an argument of type string. i.e. T.Parse(string)->T we call this
// method to convert the string to the type required by the property.
- System.Reflection.MethodInfo meth = target.GetMethod("Parse", new Type[] { typeof(string) });
- if (meth != null)
+ if (target.GetMethod("Parse", new[] { typeof(string) }) is MethodInfo meth)
{
// Call the Parse method
return meth.Invoke(null, BindingFlags.InvokeMethod, null, new object[] { txt }, CultureInfo.InvariantCulture);
@@ -222,9 +202,9 @@
/// <para>
/// </para>
/// </remarks>
- public static bool CanConvertTypeTo(Type sourceType, Type targetType)
+ public static bool CanConvertTypeTo(Type? sourceType, Type? targetType)
{
- if (sourceType == null || targetType == null)
+ if (sourceType is null || targetType is null)
{
return false;
}
@@ -236,8 +216,7 @@
}
// Look for a To converter
- IConvertTo tcSource = ConverterRegistry.GetConvertTo(sourceType, targetType);
- if (tcSource != null)
+ if (ConverterRegistry.GetConvertTo(sourceType, targetType) is IConvertTo tcSource)
{
if (tcSource.CanConvertTo(targetType))
{
@@ -246,8 +225,7 @@
}
// Look for a From converter
- IConvertFrom tcTarget = ConverterRegistry.GetConvertFrom(targetType);
- if (tcTarget != null)
+ if (ConverterRegistry.GetConvertFrom(targetType) is IConvertFrom tcTarget)
{
if (tcTarget.CanConvertFrom(sourceType))
{
@@ -280,8 +258,7 @@
}
// Look for a TO converter
- IConvertTo tcSource = ConverterRegistry.GetConvertTo(sourceType, targetType);
- if (tcSource != null)
+ if (ConverterRegistry.GetConvertTo(sourceType, targetType) is IConvertTo tcSource)
{
if (tcSource.CanConvertTo(targetType))
{
@@ -290,8 +267,7 @@
}
// Look for a FROM converter
- IConvertFrom tcTarget = ConverterRegistry.GetConvertFrom(targetType);
- if (tcTarget != null)
+ if (ConverterRegistry.GetConvertFrom(targetType) is IConvertFrom tcTarget)
{
if (tcTarget.CanConvertFrom(sourceType))
{
@@ -299,41 +275,9 @@
}
}
- throw new ArgumentException("Cannot convert source object [" + sourceInstance.ToString() + "] to target type [" + targetType.Name + "]", "sourceInstance");
+ throw new ArgumentException($"Cannot convert source object [{sourceInstance}] to target type [{targetType.Name}]", nameof(sourceInstance));
}
- // /// <summary>
- // /// Finds the value corresponding to <paramref name="key"/> in
- // /// <paramref name="props"/> and then perform variable substitution
- // /// on the found value.
- // /// </summary>
- // /// <param name="key">The key to lookup.</param>
- // /// <param name="props">The association to use for lookups.</param>
- // /// <returns>The substituted result.</returns>
- // public static string FindAndSubst(string key, System.Collections.IDictionary props)
- // {
- // if (props == null)
- // {
- // throw new ArgumentNullException("props");
- // }
- //
- // string v = props[key] as string;
- // if (v == null)
- // {
- // return null;
- // }
- //
- // try
- // {
- // return SubstituteVariables(v, props);
- // }
- // catch(Exception e)
- // {
- // LogLog.Error(declaringType, "OptionConverter: Bad option value [" + v + "].", e);
- // return v;
- // }
- // }
-
/// <summary>
/// Instantiates an object given a class name.
/// </summary>
@@ -351,23 +295,28 @@
/// not be instantiated, then <paramref name="defaultValue"/> is returned.
/// </para>
/// </remarks>
- public static object InstantiateByClassName(string className, Type superClass, object defaultValue)
+ public static object? InstantiateByClassName(string? className, Type superClass, object? defaultValue)
{
- if (className != null)
+ if (className is not null)
{
try
{
- Type classObj = SystemInfo.GetTypeFromString(className, true, true);
- if (!superClass.IsAssignableFrom(classObj))
+ Type? classObj = SystemInfo.GetTypeFromString(className, true, true);
+ if (classObj is not null)
{
- LogLog.Error(declaringType, "OptionConverter: A [" + className + "] object is not assignable to a [" + superClass.FullName + "] variable.");
- return defaultValue;
+ if (!superClass.IsAssignableFrom(classObj))
+ {
+ LogLog.Error(declaringType, $"OptionConverter: A [{className}] object is not assignable to a [{superClass.FullName}] variable.");
+ return defaultValue;
+ }
+ return Activator.CreateInstance(classObj);
}
- return Activator.CreateInstance(classObj);
+
+ LogLog.Error(declaringType, $"Could not find class [{className}].");
}
catch (Exception e)
{
- LogLog.Error(declaringType, "Could not instantiate class [" + className + "].", e);
+ LogLog.Error(declaringType, $"Could not instantiate class [{className}].", e);
}
}
return defaultValue;
@@ -425,7 +374,7 @@
while (true)
{
- j = value.IndexOf(DELIM_START, i);
+ j = value.IndexOf(DELIM_START, i, StringComparison.Ordinal);
if (j == -1)
{
if (i == 0)
@@ -451,9 +400,7 @@
j += DELIM_START_LEN;
string key = value.Substring(j, k - j);
- string replacement = props[key] as string;
-
- if (replacement != null)
+ if (props[key] is string replacement)
{
buf.Append(replacement);
}
@@ -463,10 +410,6 @@
}
}
- #endregion Public Static Methods
-
- #region Private Static Methods
-
/// <summary>
/// Converts the string representation of the name or numeric value of one or
/// more enumerated constants to an equivalent enumerated object.
@@ -475,15 +418,11 @@
/// <param name="value">The enum string value.</param>
/// <param name="ignoreCase">If <c>true</c>, ignore case; otherwise, regard case.</param>
/// <returns>An object of type <paramref name="enumType" /> whose value is represented by <paramref name="value" />.</returns>
- private static object ParseEnum(System.Type enumType, string value, bool ignoreCase)
+ private static object ParseEnum(Type enumType, string value, bool ignoreCase)
{
return Enum.Parse(enumType, value, ignoreCase);
}
- #endregion Private Static Methods
-
- #region Private Static Fields
-
/// <summary>
/// The fully qualified type of the OptionConverter class.
/// </summary>
@@ -497,7 +436,5 @@
private const char DELIM_STOP = '}';
private const int DELIM_START_LEN = 2;
private const int DELIM_STOP_LEN = 1;
-
- #endregion Private Static Fields
}
}
\ No newline at end of file
diff --git a/src/log4net/Util/PatternConverter.cs b/src/log4net/Util/PatternConverter.cs
index efa921a..d5b3a35 100644
--- a/src/log4net/Util/PatternConverter.cs
+++ b/src/log4net/Util/PatternConverter.cs
@@ -40,8 +40,6 @@
/// <author>Gert Driesen</author>
public abstract class PatternConverter
{
- #region Protected Instance Constructors
-
/// <summary>
/// Protected constructor
/// </summary>
@@ -54,25 +52,10 @@
{
}
- #endregion Protected Instance Constructors
-
- #region Public Instance Properties
-
/// <summary>
- /// Get the next pattern converter in the chain
+ /// Gets the next pattern converter in the chain.
/// </summary>
- /// <value>
- /// the next pattern converter in the chain
- /// </value>
- /// <remarks>
- /// <para>
- /// Get the next pattern converter in the chain
- /// </para>
- /// </remarks>
- public virtual PatternConverter Next
- {
- get { return m_next; }
- }
+ public virtual PatternConverter? Next => m_next;
/// <summary>
/// Gets or sets the formatting info for this converter
@@ -107,15 +90,7 @@
/// Gets or sets the option value for this converter
/// </para>
/// </remarks>
- public virtual string Option
- {
- get { return m_option; }
- set { m_option = value; }
- }
-
- #endregion Public Instance Properties
-
- #region Protected Abstract Methods
+ public virtual string? Option { get; set; }
/// <summary>
/// Evaluate this pattern converter and write the output to a writer.
@@ -130,10 +105,6 @@
/// </remarks>
public abstract void Convert(TextWriter writer, object state);
- #endregion Protected Abstract Methods
-
- #region Public Instance Methods
-
/// <summary>
/// Set the next pattern converter in the chains
/// </summary>
@@ -141,7 +112,7 @@
/// <returns>the next converter</returns>
/// <remarks>
/// <para>
- /// The PatternConverter can merge with its neighbor during this method (or a sub class).
+ /// The PatternConverter can merge with its neighbor during this method (or a subclass).
/// Therefore the return value may or may not be the value of the argument passed in.
/// </para>
/// </remarks>
@@ -173,7 +144,7 @@
}
else
{
- string msg = null;
+ string? msg;
int len;
lock (m_formatWriter)
{
@@ -214,9 +185,17 @@
}
}
- private static readonly string[] SPACES = { " ", " ", " ", " ", // 1,2,4,8 spaces
- " ", // 16 spaces
- " " }; // 32 spaces
+ private static readonly string[] SPACES =
+ {
+ // 1,2,4,8 spaces
+ " ", " ", " ", " ",
+
+ // 16 spaces
+ " ",
+
+ // 32 spaces
+ " "
+ };
/// <summary>
/// Fast space padding method.
@@ -245,25 +224,12 @@
}
}
- #endregion Public Instance Methods
-
- #region Private Instance Fields
-
- private PatternConverter m_next;
+ private PatternConverter? m_next;
private int m_min = -1;
private int m_max = int.MaxValue;
- private bool m_leftAlign = false;
+ private bool m_leftAlign;
- /// <summary>
- /// The option string to the converter
- /// </summary>
- private string m_option = null;
-
- private ReusableStringWriter m_formatWriter = new ReusableStringWriter(System.Globalization.CultureInfo.InvariantCulture);
-
- #endregion Private Instance Fields
-
- #region Constants
+ private readonly ReusableStringWriter m_formatWriter = new(System.Globalization.CultureInfo.InvariantCulture);
/// <summary>
/// Initial buffer size
@@ -275,10 +241,6 @@
/// </summary>
private const int c_renderBufferMaxCapacity = 1024;
- #endregion
-
- #region Static Methods
-
/// <summary>
/// Write an dictionary to a <see cref="TextWriter"/>
/// </summary>
@@ -304,7 +266,7 @@
}
/// <summary>
- /// Write an dictionary to a <see cref="TextWriter"/>
+ /// Writes a dictionary to a <see cref="TextWriter"/>
/// </summary>
/// <param name="writer">the writer to write to</param>
/// <param name="repository">a <see cref="ILoggerRepository"/> to use for object conversion</param>
@@ -360,16 +322,16 @@
/// the object's ToString method is called.
/// </para>
/// </remarks>
- protected static void WriteObject(TextWriter writer, ILoggerRepository repository, object value)
+ protected static void WriteObject(TextWriter writer, ILoggerRepository? repository, object? value)
{
- if (repository != null)
+ if (repository is not null)
{
repository.RendererMap.FindAndRender(value, writer);
}
else
{
// Don't have a repository to render with so just have to rely on ToString
- if (value == null)
+ if (value is null)
{
writer.Write(SystemInfo.NullText);
}
@@ -380,17 +342,9 @@
}
}
- #endregion
-
- private PropertiesDictionary properties;
-
/// <summary>
///
/// </summary>
- public PropertiesDictionary Properties
- {
- get { return properties; }
- set { properties = value; }
- }
+ public PropertiesDictionary? Properties { get; set; }
}
}
diff --git a/src/log4net/Util/PatternStringConverters/EnvironmentFolderPathPatternConverter.cs b/src/log4net/Util/PatternStringConverters/EnvironmentFolderPathPatternConverter.cs
index fb2ba93..b59452a 100644
--- a/src/log4net/Util/PatternStringConverters/EnvironmentFolderPathPatternConverter.cs
+++ b/src/log4net/Util/PatternStringConverters/EnvironmentFolderPathPatternConverter.cs
@@ -27,7 +27,6 @@
/// </summary>
/// <remarks>
/// <para>
- /// Write an special path environment folder path to the output writer.
/// The value of the <see cref="log4net.Util.PatternConverter.Option"/> determines
/// the name of the variable to output. <see cref="log4net.Util.PatternConverter.Option"/>
/// should be a value in the <see cref="System.Environment.SpecialFolder" /> enumeration.
@@ -37,7 +36,7 @@
internal sealed class EnvironmentFolderPathPatternConverter : PatternConverter
{
/// <summary>
- /// Write an special path environment folder path to the output
+ /// Writes a special path environment folder path to the output
/// </summary>
/// <param name="writer">the writer to write to</param>
/// <param name="state">null, state is not set</param>
diff --git a/src/log4net/Util/PatternStringConverters/EnvironmentPatternConverter.cs b/src/log4net/Util/PatternStringConverters/EnvironmentPatternConverter.cs
index 44428e1..98d77f0 100644
--- a/src/log4net/Util/PatternStringConverters/EnvironmentPatternConverter.cs
+++ b/src/log4net/Util/PatternStringConverters/EnvironmentPatternConverter.cs
@@ -64,7 +64,9 @@
envValue ??= Environment.GetEnvironmentVariable(Option, EnvironmentVariableTarget.Machine);
if (envValue?.Length > 0)
+ {
writer.Write(envValue);
+ }
}
}
catch (System.Security.SecurityException secEx)
@@ -80,8 +82,6 @@
}
}
- #region Private Static Fields
-
/// <summary>
/// The fully qualified type of the EnvironmentPatternConverter class.
/// </summary>
@@ -90,7 +90,5 @@
/// log message.
/// </remarks>
private static readonly Type declaringType = typeof(EnvironmentPatternConverter);
-
- #endregion Private Static Fields
}
-}
\ No newline at end of file
+}
diff --git a/src/log4net/Util/PropertiesDictionary.cs b/src/log4net/Util/PropertiesDictionary.cs
index 0bd500f..ced2c72 100644
--- a/src/log4net/Util/PropertiesDictionary.cs
+++ b/src/log4net/Util/PropertiesDictionary.cs
@@ -19,8 +19,11 @@
using System;
using System.Collections;
+using System.Collections.Generic;
using System.Runtime.Serialization;
+#nullable enable
+
namespace log4net.Util
{
/// <summary>
@@ -28,7 +31,7 @@
/// </summary>
/// <remarks>
/// <para>
- /// While this collection is serializable only member
+ /// While this collection is serializable, only member
/// objects that are serializable will
/// be serialized along with this collection.
/// </para>
@@ -38,8 +41,6 @@
[Serializable]
public sealed class PropertiesDictionary : ReadOnlyPropertiesDictionary, ISerializable, IDictionary
{
- #region Public Instance Constructors
-
/// <summary>
/// Constructor
/// </summary>
@@ -65,10 +66,6 @@
{
}
- #endregion Public Instance Constructors
-
- #region Private Instance Constructors
-
/// <summary>
/// Initializes a new instance of the <see cref="PropertiesDictionary" /> class
/// with serialized data.
@@ -84,10 +81,6 @@
{
}
- #endregion Protected Instance Constructors
-
- #region Public Instance Properties
-
/// <summary>
/// Gets or sets the value of the property with the specified key.
/// </summary>
@@ -102,15 +95,19 @@
/// a serialization operation is performed.
/// </para>
/// </remarks>
- public override object this[string key]
+ public override object? this[string key]
{
- get { return InnerHashtable[key]; }
- set { InnerHashtable[key] = value; }
+ get => base[key];
+ set => InnerHashtable[key] = value;
}
- #endregion Public Instance Properties
-
- #region Public Instance Methods
+ /// <summary>
+ /// See <see cref="IDictionary{TKey,TValue}.Add(TKey,TValue)"/>.
+ /// </summary>
+ public override void Add(string key, object? value)
+ {
+ InnerHashtable.Add(key, value);
+ }
/// <summary>
/// Remove the entry with the specified key from this dictionary
@@ -121,15 +118,11 @@
/// Remove the entry with the specified key from this dictionary
/// </para>
/// </remarks>
- public void Remove(string key)
+ public override bool Remove(string key)
{
- InnerHashtable.Remove(key);
+ return InnerHashtable.Remove(key);
}
- #endregion Public Instance Methods
-
- #region Implementation of IDictionary
-
/// <summary>
/// See <see cref="IDictionary.GetEnumerator"/>
/// </summary>
@@ -155,22 +148,12 @@
/// </remarks>
void IDictionary.Remove(object key)
{
- InnerHashtable.Remove(key);
- }
+ if (key is not string k)
+ {
+ throw new ArgumentException("key must be a string");
+ }
- /// <summary>
- /// See <see cref="IDictionary.Contains"/>
- /// </summary>
- /// <param name="key">the key to lookup in the collection</param>
- /// <returns><c>true</c> if the collection contains the specified key</returns>
- /// <remarks>
- /// <para>
- /// Test if this collection contains a specified key.
- /// </para>
- /// </remarks>
- bool IDictionary.Contains(object key)
- {
- return InnerHashtable.Contains(key);
+ InnerHashtable.Remove(k);
}
/// <summary>
@@ -199,11 +182,11 @@
/// <exception cref="ArgumentException">Thrown if the <paramref name="key"/> is not a string</exception>
void IDictionary.Add(object key, object value)
{
- if (!(key is string))
+ if (key is not string k)
{
- throw new ArgumentException("key must be a string", "key");
+ throw new ArgumentException("key must be a string", nameof(key));
}
- InnerHashtable.Add(key, value);
+ InnerHashtable.Add(k, value);
}
/// <summary>
@@ -218,10 +201,7 @@
/// returns <c>false</c>.
/// </para>
/// </remarks>
- bool IDictionary.IsReadOnly
- {
- get { return false; }
- }
+ bool IDictionary.IsReadOnly => false;
/// <summary>
/// See <see cref="IDictionary.this"/>
@@ -235,93 +215,25 @@
/// </para>
/// </remarks>
/// <exception cref="ArgumentException">Thrown if the <paramref name="key"/> is not a string</exception>
- object IDictionary.this[object key]
+ object? IDictionary.this[object key]
{
get
{
- if (!(key is string))
+ if (key is not string k)
{
- throw new ArgumentException("key must be a string", "key");
+ throw new ArgumentException("key must be a string", nameof(key));
}
- return InnerHashtable[key];
+ InnerHashtable.TryGetValue(k, out object? val);
+ return val;
}
set
{
- if (!(key is string))
+ if (key is not string k)
{
- throw new ArgumentException("key must be a string", "key");
+ throw new ArgumentException("key must be a string", nameof(key));
}
- InnerHashtable[key] = value;
+ InnerHashtable[k] = value;
}
}
-
- /// <summary>
- /// See <see cref="IDictionary.Values"/>
- /// </summary>
- ICollection IDictionary.Values
- {
- get { return InnerHashtable.Values; }
- }
-
- /// <summary>
- /// See <see cref="IDictionary.Keys"/>
- /// </summary>
- ICollection IDictionary.Keys
- {
- get { return InnerHashtable.Keys; }
- }
-
- /// <summary>
- /// See <see cref="IDictionary.IsFixedSize"/>
- /// </summary>
- bool IDictionary.IsFixedSize
- {
- get { return false; }
- }
-
- #endregion
-
- #region Implementation of ICollection
-
- /// <summary>
- /// See <see cref="ICollection.CopyTo"/>
- /// </summary>
- /// <param name="array"></param>
- /// <param name="index"></param>
- void ICollection.CopyTo(Array array, int index)
- {
- InnerHashtable.CopyTo(array, index);
- }
-
- /// <summary>
- /// See <see cref="ICollection.IsSynchronized"/>
- /// </summary>
- bool ICollection.IsSynchronized
- {
- get { return InnerHashtable.IsSynchronized; }
- }
-
- /// <summary>
- /// See <see cref="ICollection.SyncRoot"/>
- /// </summary>
- object ICollection.SyncRoot
- {
- get { return InnerHashtable.SyncRoot; }
- }
-
- #endregion
-
- #region Implementation of IEnumerable
-
- /// <summary>
- /// See <see cref="IEnumerable.GetEnumerator"/>
- /// </summary>
- IEnumerator IEnumerable.GetEnumerator()
- {
- return ((IEnumerable)InnerHashtable).GetEnumerator();
- }
-
- #endregion
}
}
-
diff --git a/src/log4net/Util/PropertyEntry.cs b/src/log4net/Util/PropertyEntry.cs
index 379a285..bac35c8 100644
--- a/src/log4net/Util/PropertyEntry.cs
+++ b/src/log4net/Util/PropertyEntry.cs
@@ -24,49 +24,17 @@
/// <summary>
/// A class to hold the key and data for a property set in the config file
/// </summary>
- /// <remarks>
- /// <para>
- /// A class to hold the key and data for a property set in the config file
- /// </para>
- /// </remarks>
public class PropertyEntry
{
- private string m_key = null;
- private object m_value = null;
-
/// <summary>
/// Property Key
/// </summary>
- /// <value>
- /// Property Key
- /// </value>
- /// <remarks>
- /// <para>
- /// Property Key.
- /// </para>
- /// </remarks>
- public string Key
- {
- get { return m_key; }
- set { m_key = value; }
- }
+ public string? Key { get; set; }
/// <summary>
/// Property Value
/// </summary>
- /// <value>
- /// Property Value
- /// </value>
- /// <remarks>
- /// <para>
- /// Property Value.
- /// </para>
- /// </remarks>
- public object Value
- {
- get { return m_value; }
- set { m_value = value; }
- }
+ public object? Value { get; set; }
/// <summary>
/// Override <c>Object.ToString</c> to return sensible debug info
@@ -74,7 +42,7 @@
/// <returns>string info about this object</returns>
public override string ToString()
{
- return "PropertyEntry(Key=" + m_key + ", Value=" + m_value + ")";
+ return $"PropertyEntry(Key={Key}, Value={Value})";
}
}
}
diff --git a/src/log4net/Util/ReadOnlyPropertiesDictionary.cs b/src/log4net/Util/ReadOnlyPropertiesDictionary.cs
index 10d77b5..1da7256 100644
--- a/src/log4net/Util/ReadOnlyPropertiesDictionary.cs
+++ b/src/log4net/Util/ReadOnlyPropertiesDictionary.cs
@@ -19,9 +19,12 @@
using System;
using System.Collections;
+using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Xml;
+#nullable enable
+
namespace log4net.Util
{
/// <summary>
@@ -29,10 +32,10 @@
/// </summary>
/// <remarks>
/// <para>
- /// This collection is readonly and cannot be modified.
+ /// This collection is readonly and cannot be modified. It is not thread-safe.
/// </para>
/// <para>
- /// While this collection is serializable only member
+ /// While this collection is serializable, only member
/// objects that are serializable will
/// be serialized along with this collection.
/// </para>
@@ -40,18 +43,9 @@
/// <author>Nicko Cadell</author>
/// <author>Gert Driesen</author>
[Serializable]
- public class ReadOnlyPropertiesDictionary : ISerializable, IDictionary
+ public class ReadOnlyPropertiesDictionary : ISerializable, IDictionary, IDictionary<string, object?>
{
- #region Private Instance Fields
-
- /// <summary>
- /// The Hashtable used to store the properties data
- /// </summary>
- private readonly Hashtable m_hashtable = new Hashtable();
-
- #endregion Private Instance Fields
-
- #region Public Instance Constructors
+ private const string ReadOnlyMessage = "This is a read-only dictionary and cannot be modified";
/// <summary>
/// Constructor
@@ -76,16 +70,12 @@
/// </remarks>
public ReadOnlyPropertiesDictionary(ReadOnlyPropertiesDictionary propertiesDictionary)
{
- foreach (DictionaryEntry entry in propertiesDictionary)
+ foreach (KeyValuePair<string, object?> entry in propertiesDictionary)
{
- InnerHashtable.Add(entry.Key, entry.Value);
+ InnerHashtable[entry.Key] = entry.Value;
}
}
- #endregion Public Instance Constructors
-
- #region Private Instance Constructors
-
/// <summary>
/// Deserialization constructor
/// </summary>
@@ -102,14 +92,10 @@
foreach (var entry in info)
{
// The keys are stored as Xml encoded names
- InnerHashtable[XmlConvert.DecodeName(entry.Name)] = entry.Value;
+ InnerHashtable[XmlConvert.DecodeName(entry.Name) ?? string.Empty] = entry.Value;
}
}
- #endregion Protected Instance Constructors
-
- #region Public Instance Properties
-
/// <summary>
/// Gets the key names.
/// </summary>
@@ -127,10 +113,40 @@
}
/// <summary>
- /// Gets or sets the value of the property with the specified key.
+ /// See <see cref="IDictionary{TKey,TValue}.ContainsKey(TKey)"/>.
+ /// </summary>
+ public bool ContainsKey(string key) => InnerHashtable.ContainsKey(key);
+
+ /// <summary>
+ /// See <see cref="IDictionary{TKey,TValue}.Add(TKey,TValue)"/>.
+ /// </summary>
+ public virtual void Add(string key, object? value)
+ {
+ throw new NotSupportedException(ReadOnlyMessage);
+ }
+
+ /// <summary>
+ /// See <see cref="IDictionary{TKey,TValue}.Remove(TKey)"/>.
+ /// </summary>
+ public virtual bool Remove(string key)
+ {
+ throw new NotSupportedException(ReadOnlyMessage);
+ }
+
+ /// <summary>
+ /// See <see cref="IDictionary{TKey,TValue}.TryGetValue(TKey,out TValue)"/>.
+ /// </summary>
+ public bool TryGetValue(string key, out object? value)
+ {
+ return InnerHashtable.TryGetValue(key, out value);
+ }
+
+ /// <summary>
+ /// Gets or sets the value of the property with the specified key.
/// </summary>
/// <value>
- /// The value of the property with the specified key.
+ /// The value of the property with the specified key, or null if a property is not present in the dictionary.
+ /// Note this is the <see cref="IDictionary"/> semantic, not that of <see cref="IDictionary{TKey,TValue}"/>.
/// </value>
/// <param name="key">The key of the property to get or set.</param>
/// <remarks>
@@ -140,16 +156,16 @@
/// a serialization operation is performed.
/// </para>
/// </remarks>
- public virtual object this[string key]
+ public virtual object? this[string key]
{
- get { return InnerHashtable[key]; }
- set { throw new NotSupportedException("This is a Read Only Dictionary and can not be modified"); }
+ get
+ {
+ InnerHashtable.TryGetValue(key, out object? val);
+ return val;
+ }
+ set => throw new NotSupportedException(ReadOnlyMessage);
}
- #endregion Public Instance Properties
-
- #region Public Instance Methods
-
/// <summary>
/// Test if the dictionary contains a specified key
/// </summary>
@@ -162,11 +178,9 @@
/// </remarks>
public bool Contains(string key)
{
- return InnerHashtable.Contains(key);
+ return InnerHashtable.ContainsKey(key);
}
- #endregion
-
/// <summary>
/// The hashtable used to store the properties
/// </summary>
@@ -178,12 +192,7 @@
/// The hashtable used to store the properties
/// </para>
/// </remarks>
- protected Hashtable InnerHashtable
- {
- get { return m_hashtable; }
- }
-
- #region Implementation of ISerializable
+ protected Dictionary<string, object?> InnerHashtable { get; } = new(StringComparer.Ordinal);
/// <summary>
/// Serializes this object into the <see cref="SerializationInfo" /> provided.
@@ -199,39 +208,27 @@
[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, SerializationFormatter = true)]
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
- foreach (DictionaryEntry entry in InnerHashtable.Clone() as IDictionary)
+ foreach (KeyValuePair<string, object?> entry in InnerHashtable)
{
- var entryKey = entry.Key as string;
- if (entryKey is null)
- {
- continue;
- }
-
- var entryValue = entry.Value;
-
// If value is serializable then we add it to the list
- var isSerializable = entryValue?.GetType().IsSerializable ?? false;
+ var isSerializable = entry.Value?.GetType().IsSerializable ?? false;
if (!isSerializable)
{
continue;
}
- // Store the keys as an Xml encoded local name as it may contain colons (':')
+ // Store the keys as an XML encoded local name as it may contain colons (':')
// which are NOT escaped by the Xml Serialization framework.
// This must be a bug in the serialization framework as we cannot be expected
// to know the implementation details of all the possible transport layers.
- var localKeyName = XmlConvert.EncodeLocalName(entryKey);
+ var localKeyName = XmlConvert.EncodeLocalName(entry.Key);
if (localKeyName is not null)
{
- info.AddValue(localKeyName, entryValue);
+ info.AddValue(localKeyName, entry.Value);
}
}
}
- #endregion Implementation of ISerializable
-
- #region Implementation of IDictionary
-
/// <summary>
/// See <see cref="IDictionary.GetEnumerator"/>
/// </summary>
@@ -241,131 +238,161 @@
}
/// <summary>
+ /// See <see cref="IEnumerable{T}.GetEnumerator"/>
+ /// </summary>
+ IEnumerator<KeyValuePair<string, object?>> IEnumerable<KeyValuePair<string, object?>>.GetEnumerator()
+ {
+ return InnerHashtable.GetEnumerator();
+ }
+
+ /// <summary>
/// See <see cref="IDictionary.Remove"/>
/// </summary>
/// <param name="key"></param>
void IDictionary.Remove(object key)
{
- throw new NotSupportedException("This is a Read Only Dictionary and can not be modified");
+ throw new NotSupportedException(ReadOnlyMessage);
}
/// <summary>
/// See <see cref="IDictionary.Contains"/>
/// </summary>
- /// <param name="key"></param>
- /// <returns></returns>
bool IDictionary.Contains(object key)
{
- return InnerHashtable.Contains(key);
+ if (key is not string k)
+ {
+ throw new ArgumentException("key must be a string");
+ }
+ return InnerHashtable.ContainsKey(k);
}
/// <summary>
- /// Remove all properties from the properties collection
+ /// See <see cref="ICollection{T}.Add(T)"/>.
+ /// </summary>
+ public void Add(KeyValuePair<string, object?> item)
+ {
+ InnerHashtable.Add(item.Key, item.Value);
+ }
+
+ /// <summary>
+ /// Removes all properties from the properties collection
/// </summary>
public virtual void Clear()
{
- throw new NotSupportedException("This is a Read Only Dictionary and can not be modified");
+ throw new NotSupportedException(ReadOnlyMessage);
}
/// <summary>
- /// See <see cref="IDictionary.Add"/>
+ /// See <see cref="ICollection{T}.Contains(T)"/>.
/// </summary>
- /// <param name="key"></param>
- /// <param name="value"></param>
+ public bool Contains(KeyValuePair<string, object?> item)
+ {
+ return InnerHashtable.TryGetValue(item.Key, out object? v) && item.Value == v;
+ }
+
+ /// <summary>
+ /// See <see cref="ICollection{T}.CopyTo(T[],int)"/>.
+ /// </summary>
+ public void CopyTo(KeyValuePair<string, object?>[] array, int arrayIndex)
+ {
+ int i = arrayIndex;
+ foreach (var kvp in InnerHashtable)
+ {
+ array[i] = kvp;
+ i++;
+ }
+ }
+
+ /// <summary>
+ /// See <see cref="ICollection{T}.Remove(T)"/>.
+ /// </summary>
+ public bool Remove(KeyValuePair<string, object?> item)
+ {
+ return InnerHashtable.Remove(item.Key);
+ }
+
+ /// <summary>
+ /// See <see cref="IDictionary.Add"/>.
+ /// </summary>
void IDictionary.Add(object key, object value)
{
- throw new NotSupportedException("This is a Read Only Dictionary and can not be modified");
+ throw new NotSupportedException(ReadOnlyMessage);
}
/// <summary>
- /// See <see cref="IDictionary.IsReadOnly"/>
+ /// See <see cref="IDictionary.IsReadOnly"/>.
/// </summary>
- bool IDictionary.IsReadOnly
- {
- get { return true; }
- }
+ bool IDictionary.IsReadOnly => true;
/// <summary>
/// See <see cref="IDictionary.this[object]"/>
/// </summary>
- object IDictionary.this[object key]
+ object? IDictionary.this[object key]
{
get
{
- if (!(key is string)) throw new ArgumentException("key must be a string");
- return InnerHashtable[key];
+ if (key is not string k)
+ {
+ throw new ArgumentException("key must be a string", nameof(key));
+ }
+ InnerHashtable.TryGetValue(k, out object? val);
+ return val;
}
- set
- {
- throw new NotSupportedException("This is a Read Only Dictionary and can not be modified");
- }
+ set => throw new NotSupportedException(ReadOnlyMessage);
}
/// <summary>
+ /// See <see cref="IDictionary{TKey,TValue}.Keys"/>.
+ /// </summary>
+ public ICollection<string> Keys => InnerHashtable.Keys;
+
+ /// <summary>
+ /// See <see cref="IDictionary{TKey,TValue}.Values"/>.
+ /// </summary>
+ public ICollection<object?> Values => InnerHashtable.Values;
+
+ /// <summary>
/// See <see cref="IDictionary.Values"/>
/// </summary>
- ICollection IDictionary.Values
- {
- get { return InnerHashtable.Values; }
- }
+ ICollection IDictionary.Values => InnerHashtable.Values;
/// <summary>
/// See <see cref="IDictionary.Keys"/>
/// </summary>
- ICollection IDictionary.Keys
- {
- get { return InnerHashtable.Keys; }
- }
+ ICollection IDictionary.Keys => InnerHashtable.Keys;
/// <summary>
/// See <see cref="IDictionary.IsFixedSize"/>
/// </summary>
- bool IDictionary.IsFixedSize
- {
- get { return InnerHashtable.IsFixedSize; }
- }
-
- #endregion
-
- #region Implementation of ICollection
+ bool IDictionary.IsFixedSize => false;
/// <summary>
/// See <see cref="ICollection.CopyTo"/>
/// </summary>
- /// <param name="array"></param>
- /// <param name="index"></param>
void ICollection.CopyTo(Array array, int index)
{
- InnerHashtable.CopyTo(array, index);
+ ((ICollection)InnerHashtable).CopyTo(array, index);
}
/// <summary>
/// See <see cref="ICollection.IsSynchronized"/>
/// </summary>
- bool ICollection.IsSynchronized
- {
- get { return InnerHashtable.IsSynchronized; }
- }
+ bool ICollection.IsSynchronized => false;
/// <summary>
/// The number of properties in this collection
/// </summary>
- public int Count
- {
- get { return InnerHashtable.Count; }
- }
+ public int Count => InnerHashtable.Count;
+
+ /// <summary>
+ /// See <see cref="IDictionary.IsReadOnly"/>.
+ /// </summary>
+ public bool IsReadOnly => true;
/// <summary>
/// See <see cref="ICollection.SyncRoot"/>
/// </summary>
- object ICollection.SyncRoot
- {
- get { return InnerHashtable.SyncRoot; }
- }
-
- #endregion
-
- #region Implementation of IEnumerable
+ object ICollection.SyncRoot => InnerHashtable;
/// <summary>
/// See <see cref="IEnumerable.GetEnumerator"/>
@@ -374,8 +401,5 @@
{
return ((IEnumerable)InnerHashtable).GetEnumerator();
}
-
- #endregion
}
}
-
diff --git a/src/log4net/Util/SystemStringFormat.cs b/src/log4net/Util/SystemStringFormat.cs
index 2a94531..65d7bc6 100644
--- a/src/log4net/Util/SystemStringFormat.cs
+++ b/src/log4net/Util/SystemStringFormat.cs
@@ -19,23 +19,16 @@
using System;
using System.Text;
-using System.Xml;
-using System.Text.RegularExpressions;
namespace log4net.Util
{
/// <summary>
/// Utility class that represents a format string.
/// </summary>
- /// <remarks>
- /// <para>
- /// Utility class that represents a format string.
- /// </para>
- /// </remarks>
/// <author>Nicko Cadell</author>
public sealed class SystemStringFormat
{
- private readonly IFormatProvider m_provider;
+ private readonly IFormatProvider? m_provider;
/// <summary>
/// Format
@@ -47,34 +40,28 @@
/// </summary>
public object[] Args { get; set; }
- #region Constructor
-
/// <summary>
/// Initialise the <see cref="SystemStringFormat"/>
/// </summary>
/// <param name="provider">An <see cref="System.IFormatProvider"/> that supplies culture-specific formatting information.</param>
/// <param name="format">A <see cref="System.String"/> containing zero or more format items.</param>
/// <param name="args">An <see cref="System.Object"/> array containing zero or more objects to format.</param>
- public SystemStringFormat(IFormatProvider provider, string format, params object[] args)
+ public SystemStringFormat(IFormatProvider? provider, string format, params object[] args)
{
m_provider = provider;
Format = format;
Args = args;
}
- #endregion Constructor
-
/// <summary>
/// Format the string and arguments
/// </summary>
/// <returns>the formatted string</returns>
- public override string ToString()
+ public override string? ToString()
{
return StringFormat(m_provider, Format, Args);
}
- #region StringFormat
-
/// <summary>
/// Replaces the format item in a specified <see cref="System.String"/> with the text equivalent
/// of the value of a corresponding <see cref="System.Object"/> instance in a specified array.
@@ -93,28 +80,28 @@
/// exception and arguments are returned in the result string.
/// </para>
/// </remarks>
- private static string StringFormat(IFormatProvider provider, string format, params object[] args)
+ private static string? StringFormat(IFormatProvider? provider, string? format, params object[]? args)
{
try
{
// The format is missing, log null value
- if (format == null)
+ if (format is null)
{
return null;
}
// The args are missing - should not happen unless we are called explicitly with a null array
- if (args == null)
+ if (args is null)
{
return format;
}
// Try to format the string
- return String.Format(provider, format, args);
+ return string.Format(provider, format, args);
}
catch (Exception ex)
{
- log4net.Util.LogLog.Warn(declaringType, "Exception while rendering format [" + format + "]", ex);
+ LogLog.Warn(declaringType, $"Exception while rendering format [{format}]", ex);
return StringFormatError(ex, format, args);
}
}
@@ -122,13 +109,13 @@
/// <summary>
/// Process an error during StringFormat
/// </summary>
- private static string StringFormatError(Exception formatException, string format, object[] args)
+ private static string StringFormatError(Exception? formatException, string? format, object[]? args)
{
try
{
- StringBuilder buf = new StringBuilder("<log4net.Error>");
+ var buf = new StringBuilder("<log4net.Error>", 100);
- if (formatException != null)
+ if (formatException is not null)
{
buf.Append("Exception during StringFormat: ").Append(formatException.Message);
}
@@ -146,7 +133,7 @@
}
catch (Exception ex)
{
- log4net.Util.LogLog.Error(declaringType, "INTERNAL ERROR during StringFormat error handling", ex);
+ LogLog.Error(declaringType, "INTERNAL ERROR during StringFormat error handling", ex);
return "<log4net.Error>Exception during StringFormat. See Internal Log.</log4net.Error>";
}
}
@@ -154,9 +141,9 @@
/// <summary>
/// Dump the contents of an array into a string builder
/// </summary>
- private static void RenderArray(Array array, StringBuilder buffer)
+ private static void RenderArray(Array? array, StringBuilder buffer)
{
- if (array == null)
+ if (array is null)
{
buffer.Append(SystemInfo.NullText);
}
@@ -164,7 +151,7 @@
{
if (array.Rank != 1)
{
- buffer.Append(array.ToString());
+ buffer.Append(array);
}
else
{
@@ -188,9 +175,9 @@
/// <summary>
/// Dump an object to a string
/// </summary>
- private static void RenderObject(Object obj, StringBuilder buffer)
+ private static void RenderObject(object? obj, StringBuilder buffer)
{
- if (obj == null)
+ if (obj is null)
{
buffer.Append(SystemInfo.NullText);
}
@@ -207,10 +194,6 @@
}
}
- #endregion StringFormat
-
- #region Private Static Fields
-
/// <summary>
/// The fully qualified type of the SystemStringFormat class.
/// </summary>
@@ -219,7 +202,5 @@
/// log message.
/// </remarks>
private static readonly Type declaringType = typeof(SystemStringFormat);
-
- #endregion Private Static Fields
}
}
diff --git a/src/log4net/Util/ThreadContextProperties.cs b/src/log4net/Util/ThreadContextProperties.cs
index 39040a6..939f8f7 100644
--- a/src/log4net/Util/ThreadContextProperties.cs
+++ b/src/log4net/Util/ThreadContextProperties.cs
@@ -19,6 +19,8 @@
using System;
+#nullable enable
+
namespace log4net.Util
{
/// <summary>
@@ -33,17 +35,11 @@
/// <author>Nicko Cadell</author>
public sealed class ThreadContextProperties : ContextPropertiesBase
{
- #region Private Instance Fields
-
/// <summary>
/// Each thread will automatically have its instance.
/// </summary>
[ThreadStatic]
- private static PropertiesDictionary _dictionary;
-
- #endregion Private Instance Fields
-
- #region Public Instance Constructors
+ private static PropertiesDictionary? _dictionary;
/// <summary>
/// Internal constructor
@@ -57,10 +53,6 @@
{
}
- #endregion Public Instance Constructors
-
- #region Public Instance Properties
-
/// <summary>
/// Gets or sets the value of a property
/// </summary>
@@ -72,26 +64,12 @@
/// Gets or sets the value of a property
/// </para>
/// </remarks>
- public override object this[string key]
+ public override object? this[string key]
{
- get
- {
- if (_dictionary != null)
- {
- return _dictionary[key];
- }
- return null;
- }
- set
- {
- GetProperties(true)[key] = value;
- }
+ get => _dictionary?[key];
+ set => GetProperties(true)![key] = value;
}
- #endregion Public Instance Properties
-
- #region Public Instance Methods
-
/// <summary>
/// Remove a property
/// </summary>
@@ -101,13 +79,7 @@
/// Remove a property
/// </para>
/// </remarks>
- public void Remove(string key)
- {
- if (_dictionary != null)
- {
- _dictionary.Remove(key);
- }
- }
+ public void Remove(string key) => _dictionary?.Remove(key);
/// <summary>
/// Get the keys stored in the properties.
@@ -116,14 +88,7 @@
/// Gets the keys stored in the properties.
/// </para>
/// <returns>a set of the defined keys</returns>
- public string[] GetKeys()
- {
- if (_dictionary != null)
- {
- return _dictionary.GetKeys();
- }
- return null;
- }
+ public string[]? GetKeys() => _dictionary?.GetKeys();
/// <summary>
/// Clear all properties
@@ -133,22 +98,12 @@
/// Clear all properties
/// </para>
/// </remarks>
- public void Clear()
- {
- if (_dictionary != null)
- {
- _dictionary.Clear();
- }
- }
-
- #endregion Public Instance Methods
-
- #region Internal Instance Methods
+ public void Clear() => _dictionary?.Clear();
/// <summary>
/// Get the <c>PropertiesDictionary</c> for this thread.
/// </summary>
- /// <param name="create">create the dictionary if it does not exist, otherwise return null if does not exist</param>
+ /// <param name="create">create the dictionary if it does not exist, otherwise return null if it does not exist</param>
/// <returns>the properties for this thread</returns>
/// <remarks>
/// <para>
@@ -157,15 +112,13 @@
/// caller must clone the collection before doing so.
/// </para>
/// </remarks>
- internal PropertiesDictionary GetProperties(bool create)
+ internal PropertiesDictionary? GetProperties(bool create)
{
- if (_dictionary == null && create)
+ if (_dictionary is null && create)
{
_dictionary = new PropertiesDictionary();
}
return _dictionary;
}
-
- #endregion Internal Instance Methods
}
}
\ No newline at end of file
diff --git a/src/log4net/Util/ThreadContextStack.cs b/src/log4net/Util/ThreadContextStack.cs
index 5beb1dd..ff72943 100644
--- a/src/log4net/Util/ThreadContextStack.cs
+++ b/src/log4net/Util/ThreadContextStack.cs
@@ -18,8 +18,8 @@
#endregion
using System;
-
using System.Collections;
+using System.Collections.Generic;
using log4net.Core;
@@ -36,16 +36,10 @@
/// <author>Nicko Cadell</author>
public sealed class ThreadContextStack : IFixingRequired
{
- #region Private Static Fields
-
/// <summary>
/// The stack store.
/// </summary>
- private Stack m_stack = new Stack();
-
- #endregion Private Static Fields
-
- #region Public Instance Constructors
+ private readonly Stack<StackFrame> m_stack = new();
/// <summary>
/// Internal constructor
@@ -59,10 +53,6 @@
{
}
- #endregion Public Instance Constructors
-
- #region Public Properties
-
/// <summary>
/// The number of messages in the stack
/// </summary>
@@ -76,14 +66,7 @@
/// minus the number of times <see cref="Pop"/> has been called.
/// </para>
/// </remarks>
- public int Count
- {
- get { return m_stack.Count; }
- }
-
- #endregion // Public Properties
-
- #region Public Methods
+ public int Count => m_stack.Count;
/// <summary>
/// Clears all the contextual information held in this stack.
@@ -100,10 +83,7 @@
/// syntax.
/// </para>
/// </remarks>
- public void Clear()
- {
- m_stack.Clear();
- }
+ public void Clear() => m_stack.Clear();
/// <summary>
/// Removes the top context from this stack.
@@ -116,14 +96,14 @@
/// empty string (not <see langword="null"/>) is returned.
/// </para>
/// </remarks>
- public string Pop()
+ public string? Pop()
{
- Stack stack = m_stack;
+ Stack<StackFrame> stack = m_stack;
if (stack.Count > 0)
{
- return ((StackFrame)(stack.Pop())).Message;
+ return stack.Pop().Message;
}
- return "";
+ return string.Empty;
}
/// <summary>
@@ -149,10 +129,10 @@
/// }
/// </code>
/// </example>
- public IDisposable Push(string message)
+ public IDisposable Push(string? message)
{
- Stack stack = m_stack;
- stack.Push(new StackFrame(message, (stack.Count > 0) ? (StackFrame)stack.Peek() : null));
+ Stack<StackFrame> stack = m_stack;
+ stack.Push(new StackFrame(message, (stack.Count > 0) ? stack.Peek() : null));
return new AutoPopStackFrame(stack, stack.Count - 1);
}
@@ -167,30 +147,26 @@
/// empty string (not <see langword="null"/>) is returned.
/// </para>
/// </remarks>
- public string Peek()
+ public string? Peek()
{
- Stack stack = m_stack;
+ Stack<StackFrame> stack = m_stack;
if (stack.Count > 0)
{
- return ((StackFrame)stack.Peek()).Message;
+ return stack.Peek().Message;
}
return "";
}
- #endregion Public Methods
-
- #region Internal Methods
-
/// <summary>
/// Gets the current context information for this stack.
/// </summary>
/// <returns>The current context information.</returns>
- internal string GetFullMessage()
+ internal string? GetFullMessage()
{
- Stack stack = m_stack;
+ Stack<StackFrame> stack = m_stack;
if (stack.Count > 0)
{
- return ((StackFrame)(stack.Peek())).FullMessage;
+ return stack.Peek().FullMessage;
}
return null;
}
@@ -201,46 +177,34 @@
/// <value>The internal storage stack</value>
/// <remarks>
/// <para>
- /// This property is provided only to support backward compatability
- /// of the <see cref="NDC"/>. Tytpically the internal stack should not
+ /// This property is provided only to support backward compatibility
+ /// of the <see cref="NDC"/>. Typically the internal stack should not
/// be modified.
/// </para>
/// </remarks>
internal Stack InternalStack
{
- get { return m_stack; }
- set { m_stack = value; }
+ get => new Stack(new Stack(m_stack));
+ set
+ {
+ m_stack.Clear();
+ var frames = (StackFrame[])value.ToArray();
+ for (int i = frames.Length - 1; i >= 0; i--)
+ {
+ m_stack.Push(frames[i]);
+ }
+ }
}
- #endregion Internal Methods
-
/// <summary>
/// Gets the current context information for this stack.
/// </summary>
- /// <returns>Gets the current context information</returns>
- /// <remarks>
- /// <para>
- /// Gets the current context information for this stack.
- /// </para>
- /// </remarks>
- public override string ToString()
- {
- return GetFullMessage();
- }
+ public override string? ToString() => GetFullMessage();
/// <summary>
/// Get a portable version of this object
/// </summary>
- /// <returns>the portable instance of this object</returns>
- /// <remarks>
- /// <para>
- /// Get a cross thread portable version of this object
- /// </para>
- /// </remarks>
- object IFixingRequired.GetFixedObject()
- {
- return GetFullMessage();
- }
+ object? IFixingRequired.GetFixedObject() => GetFullMessage();
/// <summary>
/// Inner class used to represent a single context frame in the stack.
@@ -250,17 +214,10 @@
/// Inner class used to represent a single context frame in the stack.
/// </para>
/// </remarks>
- private sealed class StackFrame
+ internal sealed class StackFrame
{
- #region Private Instance Fields
-
- private readonly string m_message;
- private readonly StackFrame m_parent;
- private string m_fullMessage = null;
-
- #endregion
-
- #region Internal Instance Constructors
+ private readonly StackFrame? m_parent;
+ private string? m_fullMessage;
/// <summary>
/// Constructor
@@ -273,21 +230,17 @@
/// with the specified message and parent context.
/// </para>
/// </remarks>
- internal StackFrame(string message, StackFrame parent)
+ internal StackFrame(string? message, StackFrame? parent)
{
- m_message = message;
+ Message = message;
m_parent = parent;
- if (parent == null)
+ if (parent is null)
{
m_fullMessage = message;
}
}
- #endregion Internal Instance Constructors
-
- #region Internal Instance Properties
-
/// <summary>
/// Get the message.
/// </summary>
@@ -297,10 +250,7 @@
/// Get the message.
/// </para>
/// </remarks>
- internal string Message
- {
- get { return m_message; }
- }
+ internal string? Message { get; }
/// <summary>
/// Gets the full text of the context down to the root level.
@@ -313,19 +263,17 @@
/// Gets the full text of the context down to the root level.
/// </para>
/// </remarks>
- internal string FullMessage
+ internal string? FullMessage
{
get
{
- if (m_fullMessage == null && m_parent != null)
+ if (m_fullMessage is null && m_parent is not null)
{
- m_fullMessage = string.Concat(m_parent.FullMessage, " ", m_message);
+ m_fullMessage = string.Concat(m_parent.FullMessage, " ", Message);
}
return m_fullMessage;
}
}
-
- #endregion Internal Instance Properties
}
/// <summary>
@@ -337,56 +285,36 @@
/// with the <see langword="using"/> pattern to remove the stack frame at the end of the scope.
/// </para>
/// </remarks>
- private struct AutoPopStackFrame : IDisposable
+ private readonly struct AutoPopStackFrame : IDisposable
{
- #region Private Instance Fields
-
/// <summary>
/// The ThreadContextStack internal stack
/// </summary>
- private Stack m_frameStack;
+ private readonly Stack<StackFrame> m_frameStack;
/// <summary>
/// The depth to trim the stack to when this instance is disposed
/// </summary>
- private int m_frameDepth;
-
- #endregion Private Instance Fields
-
- #region Internal Instance Constructors
+ private readonly int m_frameDepth;
/// <summary>
- /// Constructor
+ /// Initializes a new instance of the <see cref="AutoPopStackFrame" /> class with
+ /// the specified stack and return depth.
/// </summary>
/// <param name="frameStack">The internal stack used by the ThreadContextStack.</param>
/// <param name="frameDepth">The depth to return the stack to when this object is disposed.</param>
- /// <remarks>
- /// <para>
- /// Initializes a new instance of the <see cref="AutoPopStackFrame" /> class with
- /// the specified stack and return depth.
- /// </para>
- /// </remarks>
- internal AutoPopStackFrame(Stack frameStack, int frameDepth)
+ internal AutoPopStackFrame(Stack<StackFrame> frameStack, int frameDepth)
{
m_frameStack = frameStack;
m_frameDepth = frameDepth;
}
- #endregion Internal Instance Constructors
-
- #region Implementation of IDisposable
-
/// <summary>
/// Returns the stack to the correct depth.
/// </summary>
- /// <remarks>
- /// <para>
- /// Returns the stack to the correct depth.
- /// </para>
- /// </remarks>
public void Dispose()
{
- if (m_frameDepth >= 0 && m_frameStack != null)
+ if (m_frameDepth >= 0)
{
while (m_frameStack.Count > m_frameDepth)
{
@@ -394,8 +322,6 @@
}
}
}
-
- #endregion Implementation of IDisposable
}
}
-}
\ No newline at end of file
+}
diff --git a/src/log4net/Util/TypeConverters/ConverterRegistry.cs b/src/log4net/Util/TypeConverters/ConverterRegistry.cs
index eaf29ad..fb0b4ca 100644
--- a/src/log4net/Util/TypeConverters/ConverterRegistry.cs
+++ b/src/log4net/Util/TypeConverters/ConverterRegistry.cs
@@ -18,7 +18,7 @@
#endregion
using System;
-using System.Collections;
+using System.Collections.Concurrent;
namespace log4net.Util.TypeConverters
{
@@ -41,24 +41,8 @@
/// <seealso cref="IConvertTo"/>
/// <author>Nicko Cadell</author>
/// <author>Gert Driesen</author>
- public sealed class ConverterRegistry
+ public static class ConverterRegistry
{
- #region Private Constructors
-
- /// <summary>
- /// Private constructor
- /// </summary>
- /// <remarks>
- /// Initializes a new instance of the <see cref="ConverterRegistry" /> class.
- /// </remarks>
- private ConverterRegistry()
- {
- }
-
- #endregion Private Constructors
-
- #region Static Constructor
-
/// <summary>
/// Static constructor.
/// </summary>
@@ -72,16 +56,12 @@
// Add predefined converters here
AddConverter(typeof(bool), typeof(BooleanConverter));
AddConverter(typeof(System.Text.Encoding), typeof(EncodingConverter));
- AddConverter(typeof(System.Type), typeof(TypeConverter));
- AddConverter(typeof(log4net.Layout.PatternLayout), typeof(PatternLayoutConverter));
- AddConverter(typeof(log4net.Util.PatternString), typeof(PatternStringConverter));
+ AddConverter(typeof(Type), typeof(TypeConverter));
+ AddConverter(typeof(Layout.PatternLayout), typeof(PatternLayoutConverter));
+ AddConverter(typeof(PatternString), typeof(PatternStringConverter));
AddConverter(typeof(System.Net.IPAddress), typeof(IPAddressConverter));
}
- #endregion Static Constructor
-
- #region Public Static Methods
-
/// <summary>
/// Adds a converter for a specific type.
/// </summary>
@@ -92,13 +72,17 @@
/// Adds a converter instance for a specific type.
/// </para>
/// </remarks>
- public static void AddConverter(Type destinationType, object converter)
+ public static void AddConverter(Type? destinationType, object? converter)
{
- if (destinationType != null && converter != null)
+ if (destinationType is not null && converter is not null)
{
- lock (s_type2converter)
+ if (converter is IConvertTo convertTo)
{
- s_type2converter[destinationType] = converter;
+ s_type2ConvertTo[destinationType] = convertTo;
+ }
+ else if (converter is IConvertFrom convertFrom)
+ {
+ s_type2ConvertFrom[destinationType] = convertFrom;
}
}
}
@@ -132,32 +116,26 @@
/// Gets the type converter to use to convert values to the destination type.
/// </para>
/// </remarks>
- public static IConvertTo GetConvertTo(Type sourceType, Type destinationType)
+ public static IConvertTo? GetConvertTo(Type sourceType, Type destinationType)
{
// TODO: Support inheriting type converters.
// i.e. getting a type converter for a base of sourceType
// TODO: Is destinationType required? We don't use it for anything.
- lock (s_type2converter)
+ // Look up in the static registry
+ if (!s_type2ConvertTo.TryGetValue(sourceType, out IConvertTo? converter))
{
- // Lookup in the static registry
- IConvertTo converter = s_type2converter[sourceType] as IConvertTo;
-
- if (converter == null)
+ // Look up using attributes
+ converter = GetConverterFromAttribute(sourceType) as IConvertTo;
+ if (converter is not null)
{
- // Lookup using attributes
- converter = GetConverterFromAttribute(sourceType) as IConvertTo;
-
- if (converter != null)
- {
- // Store in registry
- s_type2converter[sourceType] = converter;
- }
+ // Store in registry
+ s_type2ConvertTo[sourceType] = converter;
}
-
- return converter;
}
+
+ return converter;
}
/// <summary>
@@ -173,30 +151,24 @@
/// Gets the type converter to use to convert values to the destination type.
/// </para>
/// </remarks>
- public static IConvertFrom GetConvertFrom(Type destinationType)
+ public static IConvertFrom? GetConvertFrom(Type destinationType)
{
// TODO: Support inheriting type converters.
// i.e. getting a type converter for a base of destinationType
- lock (s_type2converter)
+ // Lookup in the static registry
+ if (!s_type2ConvertFrom.TryGetValue(destinationType, out IConvertFrom? converter))
{
- // Lookup in the static registry
- IConvertFrom converter = s_type2converter[destinationType] as IConvertFrom;
-
- if (converter == null)
+ // Look up using attributes
+ converter = GetConverterFromAttribute(destinationType) as IConvertFrom;
+ if (converter is not null)
{
- // Lookup using attributes
- converter = GetConverterFromAttribute(destinationType) as IConvertFrom;
-
- if (converter != null)
- {
- // Store in registry
- s_type2converter[destinationType] = converter;
- }
+ // Store in registry
+ s_type2ConvertFrom[destinationType] = converter;
}
-
- return converter;
}
+
+ return converter;
}
/// <summary>
@@ -208,24 +180,18 @@
/// The type converter instance to use for type conversions or <c>null</c>
/// if no type converter is found.
/// </returns>
- private static object GetConverterFromAttribute(Type destinationType)
+ private static object? GetConverterFromAttribute(Type destinationType)
{
// Look for an attribute on the destination type
- var attributes = destinationType
- .GetCustomAttributes(typeof(TypeConverterAttribute), true);
- if (attributes is null)
- {
- // I assume the original null check is perhaps for CF or older .NET versions -- please leave in place
- return null;
- }
-
+ object[] attributes = destinationType.GetCustomAttributes(typeof(TypeConverterAttribute), true);
foreach (var attribute in attributes)
{
- var tcAttr = attribute as TypeConverterAttribute;
- if (tcAttr != null)
+ if (attribute is TypeConverterAttribute tcAttr)
{
- var converterType = SystemInfo.GetTypeFromString(destinationType, tcAttr.ConverterTypeName, false, true);
- return CreateConverterInstance(converterType);
+ if (SystemInfo.GetTypeFromString(destinationType, tcAttr.ConverterTypeName, false, true) is Type converterType)
+ {
+ return CreateConverterInstance(converterType);
+ }
}
}
@@ -248,13 +214,8 @@
/// and must have a public default (no argument) constructor.
/// </para>
/// </remarks>
- private static object CreateConverterInstance(Type converterType)
+ private static object? CreateConverterInstance(Type converterType)
{
- if (converterType == null)
- {
- throw new ArgumentNullException("converterType", "CreateConverterInstance cannot create instance, converterType is null");
- }
-
// Check type is a converter
if (typeof(IConvertFrom).IsAssignableFrom(converterType) || typeof(IConvertTo).IsAssignableFrom(converterType))
{
@@ -265,20 +226,16 @@
}
catch (Exception ex)
{
- LogLog.Error(declaringType, "Cannot CreateConverterInstance of type [" + converterType.FullName + "], Exception in call to Activator.CreateInstance", ex);
+ LogLog.Error(declaringType, $"Cannot CreateConverterInstance of type [{converterType.FullName}], exception in call to Activator.CreateInstance", ex);
}
}
else
{
- LogLog.Error(declaringType, "Cannot CreateConverterInstance of type [" + converterType.FullName + "], type does not implement IConvertFrom or IConvertTo");
+ LogLog.Error(declaringType, $"Cannot CreateConverterInstance of type [{converterType.FullName}], type does not implement IConvertFrom or IConvertTo");
}
return null;
}
- #endregion Public Static Methods
-
- #region Private Static Fields
-
/// <summary>
/// The fully qualified type of the ConverterRegistry class.
/// </summary>
@@ -288,11 +245,7 @@
/// </remarks>
private static readonly Type declaringType = typeof(ConverterRegistry);
- /// <summary>
- /// Mapping from <see cref="Type" /> to type converter.
- /// </summary>
- private static Hashtable s_type2converter = new Hashtable();
-
- #endregion
+ private static readonly ConcurrentDictionary<Type, IConvertTo> s_type2ConvertTo = new();
+ private static readonly ConcurrentDictionary<Type, IConvertFrom> s_type2ConvertFrom = new();
}
}