+带有空操作数的字符串连接运算符

时间:2013-07-25 14:07:41

标签: c# .net

一位同事向我展示了一种非常奇怪的行为,我想知道是否有人能解释我原因。

具有2个字符串参数的基本构造函数:

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

方法是:

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;
}

当在str2null的aspx页面内调用此ctor时,一切正常,因为如果字符串连接+的操作数为null,则为空字符串被替代。

但是当在后台线程中使用str2作为null调用此ctor时,会触发NullReferenceException

问题通过在使用之前测试str2 != null来解决,但我真的很想知道为什么相同的代码有时会触发异常,有时候不会![/ p>

这是堆栈跟踪:

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()

2 个答案:

答案 0 :(得分:4)

.NET Framework的字符串连接实现中存在一个模糊的错误,但它只影响了4个对象的连接,其中一个对象是非空的提供了{{{ 1}}返回null。显然,这种情况并非如此。

这种情况很可能是由以下原因引起的:

    调用ToString
  • _vars为空
  • 由于多线程应用程序中Method被滥用,_vars的内部状态已损坏,导致_vars使用运算符NullReferenceException

答案 1 :(得分:3)

问题在于Method对象的实现。自+ Operator implementation interprets a null value as an empty string以来。在str2中设置时,trueall null值永远不会进入构造函数。在相反的情况下,str1直接输入为空值,并且可能取决于实现导致空引用异常。