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()
Using the String. The String. concat() method is a good choice when we want to concatenate String objects. The empty String returned by the getNonNullString() method gets concatenated to the result, thus ignoring the null objects.
When SET CONCAT_NULL_YIELDS_NULL is ON, concatenating a null value with a string yields a NULL result. For example, SELECT 'abc' + NULL yields NULL . When SET CONCAT_NULL_YIELDS_NULL is OFF, concatenating a null value with a string yields the string itself (the null value is treated as an empty string).
The concatenation operators combine two strings to form one string by appending the second string to the right-hand end of the first string. The concatenation might occur with or without an intervening blank.
You can use the concatenation operator ( || ) to concatenate two expressions that evaluate to character data types or to numeric data types.
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_vars
in a multi-threaded application, the internal state of _vars
has been corrupted, resulting in a NullReferenceException
when operator []
is used.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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With