title: Are C# static class private fields thread safe?
body: <p>I have a C# static class accessed from multiple threads. Two questions:</p>
  
  <ol>
  <li>Are my private static fields thread safe when the field is initialized on  declaration?</li>
  <li>Should I lock when creating private static fields from within static constructor?</li>
  </ol>
  
  <p>Usage of static class from different threads:</p>
  
  <pre><code>class Program
      {
          static void Main(string[] args)
          {
              for (int i = 0; i &lt; 100; i++)
              {
                  Task.Run(() =&gt;
                  {
                      string name = MyStaticClass.GetValue(9555);
                      //...
                  });
              }
          }
  }
  </code></pre>
  
  <p>Option 1 of static class:</p>
  
  <pre><code>public static class MyStaticClass
      {
          private static MyClass _myClass = new MyClass();
  
          public static string GetValue(int key)
          {
              return _myClass.GetValue(key);
          }
      }
  </code></pre>
  
  <p>Option 2 of static class:</p>
  
  <pre><code>public static class MyStaticClass
      {
          private static MyClass _myClass;
          private static object _lockObj = new object();
  
          static MyStaticClass()
          {
              InitMyClass();
          }
  
          private static void InitMyClass()
          {
              if (_myClass == null)
              {
                  lock(_lockObj)
                  {
                      if (_myClass == null)
                      {
                          _myClass = new MyClass();
                      }
                  }
              }
          }
  
          public static string GetValue(int key)
          {
              return _myClass.GetValue(key);
          }
      }
  </code></pre>
  
  <p>Instance class created from the static class:</p>
  
  <pre><code>public class MyClass
      {
          private Dictionary&lt;int, Guid&gt; _valuesDict = new Dictionary&lt;int, Guid&gt;();
  
          public MyClass()
          {
              for (int i = 0; i &lt; 10000; i++)
              {
                  _valuesDict.Add(i, Guid.NewGuid());
              }
          }
  
          public string GetValue(int key)
          {
              if (_valuesDict.TryGetValue(key, out Guid value))
              {
                  return value.ToString();
              }
  
              return string.Empty;
          }
      }
  </code></pre>