<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-19025036</id><updated>2011-12-15T09:44:10.910+07:00</updated><title type='text'>volatile constants</title><subtitle type='html'>Volatile Constants...In the world of business, the only constant is change. And so is the software world - hence the title of my blog.

Basically I will be sharing my journey and discoveries in the .Net world (specifically in C#), MS Office Sharepoint Server 2007, and hopefully MS Commerce Server 2007 soon.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://fooshen.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19025036/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://fooshen.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>fooshen</name><uri>http://www.blogger.com/profile/15827264491456627752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>7</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-19025036.post-115389839712921875</id><published>2006-07-26T13:36:00.000+07:00</published><updated>2006-08-14T14:20:19.606+07:00</updated><title type='text'>The Nullable Conundrum</title><content type='html'>System.Nullable.. ah, what bliss.&lt;br /&gt;I've done my share of development where we resorted to use &lt;em&gt;&lt;span style="color:#3366ff;"&gt;int.MinValue&lt;/span&gt;&lt;/em&gt; or &lt;em&gt;&lt;span style="color:#3333ff;"&gt;DateTime.MinValue&lt;/span&gt;&lt;/em&gt; to represent a null value from the database, and then make the necessary behavior changes in the busineess logics to deal with it. Another path is to wrap these values using a struct. Either way, it is quite a hassle.&lt;br /&gt;&lt;br /&gt;Now with .Net 2.0, we got the System.Nullable type. And coupled with generics, suddenly we can say hello to int? or DateTime?, which is a short hand representation for System.Nullable&amp;lt;T&amp;gt;.&lt;br /&gt;&lt;br /&gt;Now here's a conundrum.&lt;br /&gt;If we do the following:&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;int? i = 1;&lt;br /&gt;object o = i; //boxing&lt;br /&gt;int? j = o as int?; //unboxing&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;will it compile?&lt;br /&gt;&lt;br /&gt;The answer is YES! Curiously, the "as" operand can be applied to nullable types.&lt;br /&gt;The IL emmitted is nothing special, it does an "isinst" test before unboxing it.&lt;br /&gt;But why the "isinst" operand can be applied to a nullable type, which in essence is a struct?&lt;br /&gt;&lt;br /&gt;The following will not compile:&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;int? i = 1;&lt;br /&gt;object o = i;&lt;br /&gt;int j = o as int; //the as operator must be used with a reference type&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The answer could lie within the way the CLR treats nullable type itself.&lt;br /&gt;A few good read from &lt;a href="http://msdn2.microsoft.com/en-us/library/b3h38hb0.aspx"&gt;MSDN&lt;/a&gt; and this posting in Somasegar's blog: &lt;a href="http://blogs.msdn.com/somasegar/archive/2005/08/11/450640.aspx"&gt;http://blogs.msdn.com/somasegar/archive/2005/08/11/450640.aspx&lt;/a&gt; shed some lights.&lt;br /&gt;But I have yet to find any documentation that states why I can use the "as" operand for nullable types.&lt;br /&gt;&lt;br /&gt;From here, we can perform some wonderful boxing gymastics:&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;int? i = 1;&lt;br /&gt;object o = i;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We can:&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;int? j = o as int?;&lt;/span&gt;&lt;br /&gt;or&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;&lt;br /&gt;int j = (int) o; //will cause a runtime error if &lt;em&gt;i&lt;/em&gt; is initialized to null&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Also:&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;int i = 1;&lt;br /&gt;object o = i;&lt;br /&gt;int? j = o as int?;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;However,&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;int? i = null;&lt;br /&gt;object o = i; //o is now a null reference, not a boxed int&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It will take a while to get used to these.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19025036-115389839712921875?l=fooshen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fooshen.blogspot.com/feeds/115389839712921875/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19025036&amp;postID=115389839712921875' title='136 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19025036/posts/default/115389839712921875'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19025036/posts/default/115389839712921875'/><link rel='alternate' type='text/html' href='http://fooshen.blogspot.com/2006/07/nullable-conundrum.html' title='The Nullable Conundrum'/><author><name>fooshen</name><uri>http://www.blogger.com/profile/15827264491456627752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>136</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19025036.post-115355876189137020</id><published>2006-07-22T15:25:00.000+07:00</published><updated>2006-07-22T16:04:17.353+07:00</updated><title type='text'>Obsolete .Net APIs</title><content type='html'>When working with threads in .Net, I usually will need the current thread Id for debugging purpose. Previously, I will just get from AppDomain.GetCurrentThreadId(). But with .Net 2.0, I get a warning that tells me this method is already obsolete, and I should use Thread.CurrentThread.ManagedThreadId instead.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://photos1.blogger.com/blogger/3019/269/1600/obsolete01.1.jpg"&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://photos1.blogger.com/blogger/3019/269/400/obsolete01.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Neat. Besides just having a tool tip that warns us of the obsolete API, Visual Studio.Net kindly warns us each time we try to build this.&lt;br /&gt;&lt;br /&gt;Now if we are writing our own classes, it is a good practice to provide the same level of warning when we obsolesce our codes. To do this, simply attribute our methods or properties with the "Obsolete" attribute. Can't get any easier than that, though this is a very obscure and seldom used attribute in our daily development.&lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;&lt;span style="color:#3333ff;"&gt;[Obsolete("Use 'DoOtherThing' instead.")]&lt;br /&gt;public void DoSomething(Guid someGuid)&lt;br /&gt;{&lt;br /&gt;//... do something...&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;For a full list of obsolete .Net APIs, refer to &lt;a href="http://msdn.microsoft.com/netframework/programming/obsoleteapi/default.aspx"&gt;.NET Framework V2.0 Obsolete API List&lt;/a&gt; on MSDN.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19025036-115355876189137020?l=fooshen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fooshen.blogspot.com/feeds/115355876189137020/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19025036&amp;postID=115355876189137020' title='64 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19025036/posts/default/115355876189137020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19025036/posts/default/115355876189137020'/><link rel='alternate' type='text/html' href='http://fooshen.blogspot.com/2006/07/obsolete-net-apis.html' title='Obsolete .Net APIs'/><author><name>fooshen</name><uri>http://www.blogger.com/profile/15827264491456627752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>64</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19025036.post-115034841306376952</id><published>2006-06-15T12:07:00.000+07:00</published><updated>2006-06-15T13:59:23.813+07:00</updated><title type='text'>Sharepoint 2007 on a Domain Controller</title><content type='html'>Recently, while trying to setup a demo system on a Virtual PC that tries to be more than one server (DC, DB, IIS...), I remembered an error that my colleague came across when running Sharepoint 2007 Beta 2 on a Domain Controller.&lt;br /&gt;&lt;br /&gt;After a site has been created, we get the message: "Microsoft Office Sharepoint Server 2007 Beta 2 Trial Period Expired".&lt;br /&gt;&lt;br /&gt;A quick google turns up the answer: &lt;a href="http://download.microsoft.com/download/b/1/a/b1a6dceb-92a3-4808-8dac-b4e40c90ce00/StandaloneDCWorkaround.msi"&gt;http://download.microsoft.com/download/b/1/a/b1a6dceb-92a3-4808-8dac-b4e40c90ce00/StandaloneDCWorkaround.msi&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is covered in David Pea's blog at &lt;a href="http://blogs.msdn.com/davidpae/archive/2006/06/01/613432.aspx"&gt;http://blogs.msdn.com/davidpae/archive/2006/06/01/613432.aspx&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19025036-115034841306376952?l=fooshen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fooshen.blogspot.com/feeds/115034841306376952/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19025036&amp;postID=115034841306376952' title='20 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19025036/posts/default/115034841306376952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19025036/posts/default/115034841306376952'/><link rel='alternate' type='text/html' href='http://fooshen.blogspot.com/2006/06/sharepoint-2007-on-domain-controller.html' title='Sharepoint 2007 on a Domain Controller'/><author><name>fooshen</name><uri>http://www.blogger.com/profile/15827264491456627752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>20</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19025036.post-114924024222049025</id><published>2006-06-02T15:00:00.000+07:00</published><updated>2006-06-02T16:52:05.823+07:00</updated><title type='text'>Implicit vs Explicit Casting</title><content type='html'>Once a while I get the question on using the "as" operator in C# as opposed to casting.&lt;br /&gt;&lt;br /&gt;For example:&lt;br /&gt;&lt;span style="font-family:arial;color:#3366ff;"&gt;1. Customer c = obj as Customer;  &lt;br /&gt;2. Customer c = (Customer) obj;  //explicit cast&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Our common understanding on the difference between statement 1 and statement 2 is that:&lt;br /&gt;1. Will return null if &lt;i&gt;obj&lt;/i&gt; is not a Customer instance.&lt;br /&gt;2. Will throw an exception if &lt;i&gt;obj&lt;/i&gt; cannot be converted into Customer type.&lt;br /&gt;&lt;br /&gt;The underlying difference in IL is that the "as" keyword is emitted as an &lt;b&gt;"isinst"&lt;/b&gt; opcode, which will check whether &lt;i&gt;obj&lt;/i&gt; is an instance of the specified type or not and return null if not; while explicit casting is a call to &lt;b&gt;"op_Explicit"&lt;/b&gt; method of the instance.&lt;br /&gt;&lt;br /&gt;What does this mean? From here, we know that "as" cannot be used on value types (because &lt;b&gt;"isinst"&lt;/b&gt; tests for instances).&lt;br /&gt;&lt;br /&gt;However, there's more to that. One important thing to be aware of is that casting is a conversion operator that can be overloaded; and there are two types of conversion:&lt;br /&gt;&lt;br /&gt;1. Explicit conversion&lt;br /&gt;- This requires an explicit casting, as in:&lt;br /&gt;&lt;span style="font-family:arial;color:#3366ff;"&gt;&lt;br /&gt;Employee e1 = new Employee();&lt;br /&gt;Customer c = (Customer) e1;   //explicit&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;2. Implicit conversion&lt;br /&gt;- This is done automatically, as in:&lt;br /&gt;&lt;span style="font-family:arial;color:#3366ff;"&gt;&lt;br /&gt;Employee e1 = new Employee();&lt;br /&gt;Customer c = e1;  //implicit&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;For both explicit and implicit conversion, there is only one rule: The conversion must be static.&lt;br /&gt;&lt;br /&gt;To declare an explicit conversion, we can do this:&lt;br /&gt;&lt;span style="font-family:arial;color:#3366ff;"&gt;public static explicit operator Employee(Customer cust)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return new Employee(cust.CustomerId);&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To do an implicit conversion, simply replace the keyword explicit with implicit.&lt;br /&gt;However, there is one small detail going on here. If we declare an explicit conversion and we try to do this:&lt;br /&gt;&lt;span style="font-family:arial;color:#3366ff;"&gt;Customer cust = new Customer();&lt;br /&gt;Employee e = cust;   //this will fail!&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We will get a compile-time error because our code is trying to implicitly cast &lt;i&gt;cust&lt;/i&gt; to &lt;i&gt;Employee&lt;/i&gt; type while having an explicit conversion.&lt;br /&gt;&lt;br /&gt;However, if we declare an implicit conversion, we can do the following:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;color:#3366ff;"&gt;//line number for reference purpose&lt;br /&gt;1. Customer cust = new Customer();&lt;br /&gt;2. Employee e1 = cust;                //implicit&lt;br /&gt;3. Employee e2 = (Employee) cust;     //explicit &lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What's going on here? &lt;/b&gt;&lt;br /&gt;The secret lies with the C# compiler. Inspecting the IL, line 2 and 3 will emit the same call to &lt;b&gt;"op_Implicit"&lt;/b&gt; for Customer. Another "implicit" sleight-of-hand by the compiler.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;"op_Explicit"&lt;/b&gt; and &lt;b&gt;"op_Implicit"&lt;/b&gt; are not IL opcodes, but are emitted by the compiler for the static explicit/implicit conversion method.&lt;br /&gt;&lt;br /&gt;Typically, explicit conversion should be used in situations where it can result in data-loss (for example, casting &lt;i&gt;long&lt;/i&gt; to &lt;i&gt;int&lt;/i&gt;), while implicit conversion should be used in cases where it is guaranteed not to result in data loss (&lt;i&gt;int&lt;/i&gt; to &lt;i&gt;long&lt;/i&gt;).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19025036-114924024222049025?l=fooshen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fooshen.blogspot.com/feeds/114924024222049025/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19025036&amp;postID=114924024222049025' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19025036/posts/default/114924024222049025'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19025036/posts/default/114924024222049025'/><link rel='alternate' type='text/html' href='http://fooshen.blogspot.com/2006/06/implicit-vs-explicit-casting.html' title='Implicit vs Explicit Casting'/><author><name>fooshen</name><uri>http://www.blogger.com/profile/15827264491456627752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19025036.post-114889386061722178</id><published>2006-05-29T15:09:00.000+07:00</published><updated>2006-05-29T16:33:21.006+07:00</updated><title type='text'>Sharepoint 2007: The neat and tidy</title><content type='html'>After installing Sharepoint 2007 Beta2, the very first thing I noticed (besides all the bells and whistles), is the superior user interface; souped up with ajax at every turn. There is hardly any dropdownlist box, replaced with a rather sweet DHTML drop down menu that loads asynchronously.&lt;br /&gt;&lt;br /&gt;Now, the one thing that caught my eye is the PeopleEditor control (part of Sharepoint's WebControl library). This is used in many security settings page, for example in the site collection adminitration page as shown here.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://photos1.blogger.com/blogger/3019/269/1600/sharepoint2k7_001.jpg"&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 332px; CURSOR: hand; HEIGHT: 130px; TEXT-ALIGN: center" height="171" alt="" src="http://photos1.blogger.com/blogger/3019/269/320/sharepoint2k7_001.jpg" width="378" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;What these controls do is quite similar to those outlook email fields, where we can type in an alias, and click on the "Check Names" image button to resolve the actual user name. Once resolved, the name will be underlined, or if unresolved, you will see the red wavy underline, similar to a typical spell-check error in a word processor.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://photos1.blogger.com/blogger/3019/269/1600/sharepoint2k7_002.jpg"&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://photos1.blogger.com/blogger/3019/269/400/sharepoint2k7_002.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now, &lt;b&gt;How the heck do they do it - Part one.&lt;/b&gt;&lt;br /&gt;Conventionally, we can apply a 'text-decoration: underline' to a text input control (IE-only), to achieve an effect close to the first text-box (the "resolved" name). However, what about the wavy underline thingie? It is not supported by any standard CSS implementations. The trick is to use a small image with a red underline, and set background-repeat attribute to repeat-x in the stylesheet.&lt;br /&gt;&lt;br /&gt;In Sharepoint 2007, the CSS class used is &lt;i&gt;ms-entity-resolved&lt;/i&gt; and &lt;i&gt;ms-entity-unresolved&lt;/i&gt; respectively. Now, if we apply these attributes to a normal text-input, we get another problem. If we apply the above styles into a conventional &amp;lt;input type="text"&amp;gt; element, all we got is a textbox that applies the underline/wavy-underline in the &lt;b&gt;entire&lt;/b&gt; input. Not good, as in Sharepoint 2007, we get to see this:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://photos1.blogger.com/blogger/3019/269/1600/sharepoint2k7_003.jpg"&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://photos1.blogger.com/blogger/3019/269/400/sharepoint2k7_003.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How the heck do they do it - Part two.&lt;/b&gt;&lt;br /&gt;Furthermore, if we use the left/right arrow, the cursor will actually skip past the resolved/unresolved name, treating the entity as if one single character.&lt;br /&gt;&lt;br /&gt;So, how the heck.. ? Well, to achieve this level of neatness, Sharepoint 2007 employes various DHTML tricks.. and most are specific to IE only. To achieve the above behaviour, Sharepoint &lt;b&gt;didn't use any textbox&lt;/b&gt; input elements as we were made to believe. Yes, what we see here are not &amp;lt;input type="textbox"&amp;gt; tags; rather these are done using nested div and span, with the IE-specific attribute "&lt;b&gt;contenteditable&lt;/b&gt;" set to "true".&lt;br /&gt;&lt;br /&gt;To try this, use the following code snippet:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="color:#3366ff;"&gt;&lt;br /&gt;&amp;lt;style&amp;gt;&lt;br /&gt;.squiggle&lt;br /&gt;{&lt;br /&gt;   background-image:url("squiggle.gif");&lt;br /&gt;   background-repeat:repeat-x;&lt;br /&gt;   background-position:left bottom;&lt;br /&gt;   padding-bottom:2px;&lt;br /&gt;   vertical-align:text-top;&lt;br /&gt;   font-style:italic;&lt;br /&gt;}&lt;br /&gt;.container&lt;br /&gt;{&lt;br /&gt;   border:1px solid #a5a5a5;  &lt;br /&gt;   overflow-x: hidden;&lt;br /&gt;   width: 100%;&lt;br /&gt;   color: windowtext;&lt;br /&gt;   height: 18px;&lt;br /&gt;   background-color: window&lt;br /&gt;}&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&amp;lt;div class="container" contenteditable="true" tabindex="0"&amp;gt;&lt;br /&gt;&amp;lt;span class="squiggle" contenteditable="false" tabindex="-1"&amp;gt;&lt;br /&gt;&amp;lt;div style="DISPLAY: none" displaytext="here"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;span contenteditable="true" tabindex="-1"&amp;gt;unresolved!&amp;lt;/span&amp;gt;&lt;br /&gt;&amp;lt;/span&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;By the way, the squiggle.gif image can be found in Sharepoint's Template\Images folder.&lt;br /&gt;&lt;br /&gt;This is the magnified version of it (200x): &lt;a href="http://photos1.blogger.com/blogger/3019/269/1600/SQUIGGLE_enlarged200x.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/3019/269/400/SQUIGGLE_enlarged200x.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;Cool tricks to use, especially if we are creating controls with spell checks capabilities!&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Note: As of today, these are only availble in IE. In FireFox, Sharepoint will simply render a textarea control.&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19025036-114889386061722178?l=fooshen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fooshen.blogspot.com/feeds/114889386061722178/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19025036&amp;postID=114889386061722178' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19025036/posts/default/114889386061722178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19025036/posts/default/114889386061722178'/><link rel='alternate' type='text/html' href='http://fooshen.blogspot.com/2006/05/sharepoint-2007-neat-and-tidy.html' title='Sharepoint 2007: The neat and tidy'/><author><name>fooshen</name><uri>http://www.blogger.com/profile/15827264491456627752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19025036.post-114870366895980344</id><published>2006-05-27T10:47:00.000+07:00</published><updated>2006-05-27T11:26:58.633+07:00</updated><title type='text'>The StringBuilder Code</title><content type='html'>&lt;span style="font-family:arial;"&gt;Common understanding is that, when we need to concatenate a few strings together to make a happy string, we will typically use StringBuilder, having heard so many preaching about the performance gain as opposed to using the "+" operator.&lt;br /&gt;&lt;br /&gt;Well that is true in almost all situations. However, there are a few misconceptions as well. Typically, a StringBuilder object comes in handy when we are building the strings in a loop, and the number of string variables exceed 5 or more. When using StringBuilder to concatenate less than that amount of string, it becomes a hinder to performance rather than helping it as we know there are overheads involved in initializing the StringBuilder object.&lt;br /&gt;&lt;br /&gt;Now, for small amount of string, we should use String.Concat(), it can't get any faster than that. Which means, the following code in Snippet B is not as good as Snippet A.&lt;br /&gt;&lt;br /&gt;Code Snippet A &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="color:#3366ff;"&gt;static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;string output1 = "Hello";&lt;br /&gt;string output2 = "World";&lt;br /&gt;&lt;br /&gt;Console.WriteLine(output1 + output2);&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Code Snippet B &lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#3366ff;"&gt;&lt;span style="font-family:arial;"&gt;static void Main(string[] args)&lt;br /&gt;{&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#3366ff;"&gt;&lt;span style="font-family:arial;"&gt;string output1 = "Hello";&lt;br /&gt;string output2 = "World";&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="color:#3366ff;"&gt;Console.WriteLine(String.Concat(output1, output2));&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The answer is NO. They are both the SAME!&lt;br /&gt;Why? Simply inspect the IL code using ILDASM, we see&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;.method private hidebysig static void Main(string[] args) cil managed&lt;br /&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span style="color:#3366ff;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;span style="color:#3366ff;"&gt;.entrypoint&lt;br /&gt;.custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 )&lt;br /&gt;// Code size 25 (0x19)&lt;br /&gt;.maxstack 2&lt;br /&gt;.locals init (string V_0, string V_1)&lt;br /&gt;IL_0000: ldstr "Hello"&lt;br /&gt;IL_0005: stloc.0&lt;br /&gt;IL_0006: ldstr "World"&lt;br /&gt;IL_000b: stloc.1&lt;br /&gt;IL_000c: ldloc.0&lt;br /&gt;IL_000d: ldloc.1&lt;br /&gt;IL_000e: call string [mscorlib]System.String::Concat(string,string)&lt;br /&gt;IL_0013: call void [mscorlib]System.Console::WriteLine(string)&lt;br /&gt;IL_0018: ret&lt;br /&gt;} // end of method StringPerformance::Main&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Both codes compiled to the same IL. C#'s compiler itself actually optimizes the string concatenation to use string.concat.&lt;br /&gt;&lt;br /&gt;Final word: Don't abuse StringBuilder. Use when concatenating a dynamically growing number of strings.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19025036-114870366895980344?l=fooshen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fooshen.blogspot.com/feeds/114870366895980344/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19025036&amp;postID=114870366895980344' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19025036/posts/default/114870366895980344'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19025036/posts/default/114870366895980344'/><link rel='alternate' type='text/html' href='http://fooshen.blogspot.com/2006/05/stringbuilder-code.html' title='The StringBuilder Code'/><author><name>fooshen</name><uri>http://www.blogger.com/profile/15827264491456627752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19025036.post-114862679135175467</id><published>2006-05-26T13:59:00.000+07:00</published><updated>2006-05-26T13:59:51.350+07:00</updated><title type='text'></title><content type='html'>The obligatory "Hello World!"&lt;br /&gt;I am a software consultant, working primarily on Microsoft's .Net platform.&lt;br /&gt;All articles posted here are solely of my personal views and/or opinions, and does not represent any party that I am or may be professionally affiliated with.&lt;br /&gt;&lt;br /&gt;&lt;div align="center"&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://photos1.blogger.com/blogger/3019/269/200/MCSD-RGB_small.0.jpg" border="0" /&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19025036-114862679135175467?l=fooshen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://fooshen.blogspot.com/feeds/114862679135175467/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19025036&amp;postID=114862679135175467' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19025036/posts/default/114862679135175467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19025036/posts/default/114862679135175467'/><link rel='alternate' type='text/html' href='http://fooshen.blogspot.com/2006/05/obligatory-hello-world-i-am-software.html' title=''/><author><name>fooshen</name><uri>http://www.blogger.com/profile/15827264491456627752</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
