this.Session[key] = "foo"; if ((this.Session[key] ?? string.Empty) == "foo") { //do stuff }
当然,这会产生“可能的非预期参考比较按预期工作”的情况.这里有很好的解决方案,我已经知道修复是在看到代码后立即将会话变量强制转换为字符串.
但是,代码已有多年历史,并且自最初编写以来从未更改过.直到本周在我们的测试环境中,if语句被评估为true并执行// do stuff部分.这个错误的代码仍然在我们的生产环境中按预期工作.
怎么会这样?这些编写的代码没有理由按照预期工作;然而它确实如此,并且仍然在生产中.什么会改变,使这个代码不应该工作,但做了,突然停止工作(或者更确切地说,表现得像它应该有的)?
解决方法
The common language runtime conserves string storage by maintaining a table,called the intern pool,that contains a single reference to each unique literal string declared or created programmatically in your program. Consequently,an instance of a literal string with a particular value only exists once in the system.
For example,if you assign the same literal string to several variables,the runtime retrieves the same reference to the literal string from the intern pool and assigns it to each variable.
这就是object.ReferenceEquals(“foo”,“foo”)为真的原因.
如果对动态创建的字符串执行相同操作,则不会实现该字符串,并且引用将不相等
object str = new StringBuilder().Append("f").Append("oo").ToString(); // str = "foo" object.ReferenceEquals(str,"foo"); // false
字符串实习可以根据实现的不同而有所不同,这就是为什么在通过引用比较字符串时可以在不同环境中获得不同的行为.