Un collaboratore mi ha mostrato un comportamento molto strano e mi piacerebbe sapere se qualcuno potrebbe spiegarmi perché.+ operatore concat stringa con un operando null
Un costruttore di base con 2 params stringa:
public MyClass(string str1, string str2)
{
this.s1 = str1;
this.s2 = str2;
this.s3 = Method(str2 + "._className", str1);
}
metodo è:
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;
}
Quando questo ctor viene chiamato all'interno di una pagina aspx con str2
come null
, tutto funziona benissimo, perché se un operando di concatenazione di stringhe +
è null
, una stringa vuota viene sostituita.
Tuttavia, quando questo ctor viene chiamato con str2
come null
in un thread in background, viene generato un NullReferenceException
.
Il problema è stato risolto testando str2 != null
prima di utilizzarlo, ma mi piacerebbe davvero sapere perché lo stesso codice genera talvolta un'eccezione, a volte no!
Ecco la traccia dello stack:
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()
Mi sento come se qualcos'altro stia succedendo qui. A cosa serve 'this.s2'? Qual è la traccia dello stack? Puoi pubblicare un codice riproducibile con cui testarci? Dove stai facendo il controllo nulla? È prima di istanziare 'MyClass' o prima di eseguire' Method' o all'inizio del costruttore? –
Sei sicuro di aver rintracciato il problema nella parte corretta del codice? Cosa fa 'Method'? –
Sei sicuro? hai provato la stessa combinazione in thread in background? –