Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a readonly field in .NET become null?

I have a strange bug in a multithreaded app:

public class MyClass
{
   private readonly Hashtable HashPrefs;
   public MyClass(int id)
  {
     HashPrefs = new Hashtable();
  } 

  public void SomeMethodCalledFromAnotherThread(string hashKey,string hashValue)
 {
    if (HashPrefs.Contains(hashKey))  // <-- throws NullReferenceException
    {

    }
 }
}

One thread does the :

 SomeQueue.Add(new MyClass(1));

And another thread does the :

 SomeQueue.Dequeue().SomeMethodCalledFromAnotherThread(SomeClass.SomeMethod(),"const value"); 

But how can the second thread call the method before the constructor is finished?

Edit: I added the part with the function parameters, as it seems this might be relevant. As far as I can tell, the hashKey being passed on cannot be null, as SomeMethod() always returns a relevant string.

As others have pointed out,if the problem was a null haskKey parameter passed to the Contains() , the exception would be ArgumentNullException.

like image 905
Radu094 Avatar asked Dec 07 '09 17:12

Radu094


People also ask

Can readonly value be change in C#?

Use the readonly keyword in C# This means that the variable or object can be assigned a value at the class scope or in a constructor only. You cannot change the value or reassign a value to a readonly variable or object in any other method except the constructor.

What is the use of private readonly in C#?

If it's private and readonly , the benefit is that you can't inadvertently change it from another part of that class after it is initialized. The readonly modifier ensures the field can only be given a value during its initialization or in its class constructor.

How do you declare a readonly variable in C#?

In C#, you can use a readonly keyword to declare a readonly variable. This readonly keyword shows that you can assign the variable only when you declare a variable or in a constructor of the same class in which it is declared.

What is readonly and constant in C#?

readonly keyword is used to define a variable which can be assigned once after declaration either during declaration or in constructor. const keyword is used to define a constant to be used in the program. Following is the valid usage of a readonly and const keywords in C#.


1 Answers

Reflection is one way to do this (SetField).

A second way to get this curiosity is if you give away the reference too early, by passing this (or sometihng involving an implicit this, such as a field captured into an anonymous method / lambda) out of the .ctor:

public MyClass(int id)
{
    Program.Test(this); // oopsie ;-p
    HashPrefs = new Hashtable();
}

Or more likely (given the question):

SomeQueue.Add(this);

Another relevant question might be - can it not be assigned in the first place? And the answer to that is yes, especially if you are using serialization. Contrary to popular belief, you can actually bypass the constructors, if you have a reason; DataContractSerializer is a good example of something that does this...

The following will create a MyClass with a null field:

MyClass obj = (MyClass)
    System.Runtime.Serialization.FormatterServices.GetUninitializedObject(
        typeof(MyClass));
like image 197
Marc Gravell Avatar answered Oct 19 '22 04:10

Marc Gravell