Sylv21
Sylv21

Reputation: 345

+ string concat operator with a null operand

A co-worker showed me a very strange behavior and I'd like to know if someone could explain me why.

A basic constructor with 2 string params:

    public MyClass(string str1, string str2)
    {
        this.s1 = str1;
        this.s2 = str2;
        this.s3 = Method(str2 + "._className", str1);
    }

Method is:

public string Method(string key, string defaultValue)
{
    List<string> list = _vars[key];
    if (list == null) return defaultValue;
    string res = "";
    foreach (string s in list)
    {
        if (res != "") res += ",";
        res += s;
    }
    return res;
}

When this ctor is called within an aspx page with str2 as null, all works fine because if an operand of string concatenation + is null, an empty string is substituted.

But when this ctor is called with str2 as null in a background thread, a NullReferenceException is fired.

The problem was solved by testing str2 != null before using it, but I'd really like to know why the same code sometimes fires an exception, sometimes not!

Here is the stack trace:

Exception: System.NullReferenceException 
Message: Object reference not set to an instance of an object.
StackTrace: 
at MyClass..ctor(String str1, String str2) 
at AbandonedCartsNotificationJob.NotifyAbandonedCarts() in AbandonedCartsNotificationJobPartial.cs:line 39 
at AbandonedCartsNotificationJob.work() in AbandonedCartsNotificationJob.cs:line 15 
at MyRuntime.JobManager.run() 
at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
at System.Threading.ExecutionContext.runTryCode(Object userData) 
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData) 
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) 
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
at System.Threading.ThreadHelper.ThreadStart()

Upvotes: 8

Views: 449

Answers (2)

Sam Harwell
Sam Harwell

Reputation: 99859

There was an obscure bug in the .NET Framework's implementation of string concatenation, but it only affected concatenations of 4 objects, where one of the objects is non-null and provided an override of ToString that returned null. Clearly that situation isn't the case here.

This situation is most likely caused by one of the following:

  • _vars is null when Method is called
  • Due to a misuse of _vars in a multi-threaded application, the internal state of _vars has been corrupted, resulting in a NullReferenceException when operator [] is used.

Upvotes: 4

Marwie
Marwie

Reputation: 3307

The problem lies in the implementation of the Method Object. Since the + Operator implementation interprets a null value as an empty string. The actuall null value never enters the constructor when set in str2. On the Opposite, str1 directly enters as null value and may depending on the implementation cause a null reference exception.

Upvotes: 3

Related Questions