周末熬夜终于搞定的AOP尝鲜系列文章第三篇一出,就收到了很多朋友的反馈和邮件。首先感谢大家的关注!也衷心谢谢给我指出文章错误、文字疏忽的朋友们!

有一位细心朋友今早给我发来邮件,“批评”我又在简单问题上面犯了糊涂,他所指的是文章中出现的这个语句:

Console.WriteLine("Add: " + Thread.CurrentContext);

其中Thread.CurrentContext属性将返回当前线程所处的执行环境,类型是System.Runtime.Remoting.Contexts名称空间中的Context。一个字串常量怎么可以和一个对象直接相加呢!肯定是我忘了写ToString()了吧?他对此的评语也很有意思,“老兄以为在写JScript呐!”……嘿嘿!一针见血啊!

我回复他,感谢他的热心和仔细(再次:),顺便问了一句:我文中的代码你动手编译过吗?因为我清楚的记得像这样的代码我已经不是写一次两次了——偶的实践经验告诉我:这个语句是可以在Visual C# .NET中编译并正确运行的!不仅如此,我还经常写这样的语句:

string tempFilename = null;
tempFilename += Environment.TickCount + ".tmp"; // 啊?string += int?

或者:

string guidKey = "{" + Guid.NewGuid() + "}"; // 奋特!

再或者:

string logLine = "Log: " + DateTime.Now; // 咣当……

……就像读者所说:这是C#还是JScript啊!?实际上,我也没有在C#语言规范中找到能解释这个现象的理论依据(如果你知道的话希望能告诉我:)。所以我只能说这是Visual C# .NET编译器的一种编译器优化手段造成的side effect(将静态字串相加转化为String.Concat()调用)——不过事实证明,这种写法的效率比起String.Format()还要高(虽然没有人家灵活),甚至有时候比每一个用ToString()还要快!原因是什么?也很容易分析出来,留给聪明的你做个练习吧(可以把你的想法用反馈告诉我)!:)

最后还是按照惯例,做个练习——想想下面这个表达式中对quiz求值将是什么结果?

string quiz = null;
quiz += 1 + 2 + "3" + 4 + 5;

P.S: USE THIS TRICK AT YOUR OWN RISK! AND IT IS NOT RECOMMENDED AT ALL (THOUGH IT'S OFTEN USEFUL AND HANDY DURING DEBUGGING.)