周末熬夜终于搞定的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.)
打印 | 张贴于 2004-04-05 21:31:00 | Tag:.NET Stuffs
留言反馈
1 & 2 & "3" & 4 & 5
不会造成任何理解困难,结果就是“12345”
另外我想+如果是从左到右计算的话,那
1 + 2 + "3" + 4 + 5
结果应当是"3345"
只有VB这种垃圾语言才会有运算符,C#并不鼓励用+来操作字符串,String.Format才是王道,对于复杂的字符串生成,则有StringBuilder伺候。+生成大量临时字符串,效率很成问题
string str = 3 + "3" + 4 + 5;
String.Concat( Object, Object );
String.Concat(params[] string strs)
关键是你想调用哪个重载方法,当然是尽量调用不会执行box的、性能高的。
不过对于一般的object类型,如果要作为某种具体的类型,例如string,int。最好还是用tostring()或Convert.to...()操作来完成。这样似乎显得更严谨。
.Net本质论好像说过这个问题。
这个语句最后会导致这样的一个调用:
static String String.Concat( Object, Object );
就是说:IL代码会先将值类型123进行装箱操作,装箱成一个Object,然后调用Concat(Object, Object),将每个Object参数的String形式连接起来,并返回最终的String,然后调用:
Console.WriteLine( String )
来完成操作。
不过偶学知识大多也正是如此先有实践再求理论的说,嘿嘿……
谢谢各位的反馈。
string s = "" + i;
C# learned it.
谢谢你的信息!看来我读的还是不够仔细——现在也没有找到这段话在C# Language Specification中的出处。能否告诉我这是在规范的哪一章节?
@all:
还是那句话,在容易引起歧义的情况中不建议使用这种写法。不过既然规范里面明确提到了这种表达式的正确性,那么我想合理的使用也算不得错——只要代码可读性好,同时不影响执行性能就是了。所以所有批判1+2+"3"+4+5的朋友们都是有责任心的good programmers(当然我自己也绝对不会写这样的东西出来,呵呵,写出来只是为了加深对此问题的印象——也许有一天碰到与之相关的bug时这就是一条线索呢)。
当一个或两个操作数为 string 类型时,二元 + 运算符执行字符串串联。在字符串串联运算中,如果它的一个操作数为 null,则用空字符串来替换此操作数。否则,任何非字符串参数都通过调用从 object 类型继承的虚 ToString 方法,转换为它的字符串表示形式。如果 ToString 返回 null,则替换成空字符串。
-------
不是说得很明白吗?
也是java 1.5 版本中特别强调的亮点
没想到C#已经实现了
当然,严谨是最好的。
1 & 2 & "3" & 4 & 5
不会造成任何理解困难,结果就是“12345”
另外我想+如果是从左到右计算的话,那
1 + 2 + "3" + 4 + 5
结果应当是"3345"