I’ve used the snippet of code at the end of this article twice in the last week to clear up some misunderstandings about strings in .NET.
System.String is a reference type in .NET. Don’t let anyone mislead you into thinking otherwise. You’ll hear people saying strings “act like value types”, but this doesn’t mean the runtime makes a copy of the string during assignment operations, and it doesn’t make a copy of a string when passing the string as a parameter.
The equality operator and String.Equals method compare the values of two string objects, and you won’t find a property or method on System.String with the ability to modify the contents of a string – only return a new string object. Because of these two behaviors we sometimes say strings have value type semantics (they feel like value types), but strings are reference types in the runtime. An assignment operation does not copy a string, but assigns a reference. The value given to a string parameter in a method call is the reference, not a copy of the string’s value.
using System;
class Class1
{
[STAThread]
static void Main(string[] args)
{
string s1 = "Hello";
string s2 = s1;
// this test will compare the values of the strings
// result will be TRUE since both s1 and s2
// refer to a string with the value "Hello"
bool result = String.Equals(s1, s2);
Console.WriteLine("String.Equals(s1, s2) = {0}", result);
// next we will check identity
// ReferenceEquals will return true if both parameters
// point to the same object
// result will be TRUE -both s1 and s2reference
// the same object.
// strings are reference types
// there is no copy made on assignment (s2 = s1)
result = Object.ReferenceEquals(s1, s2);
Console.WriteLine("Object.ReferenceEquals(s1, s2) = {0}", result);
// now we will make a copy of the string
s2 = String.Copy(s1);
// compare string values again
// result will be TRUE - both s1 and s2
// refer tostrings with the value of "Hello"
result = String.Equals(s1, s2);
Console.WriteLine("String.Equals(s1, s2) = {0}", result);
// check identity again
// result will be FALSE
// s1 and s2 point to different object instancesbecause we forced a copy
result = Object.ReferenceEquals(s1, s2);
Console.WriteLine("Object.ReferenceEquals(s1, s2) = {0}", result);
}
}
I’m was waiting in the drive-thru lane at the bank today when I picked up the June 2005 issue of Dr. Dobb’s Journal from my backseat. Reading an engrossing article in the car is a fun way to meet new people. When the person behind me honks and shouts “Pay attention, moron! Move forward!”, I know what they are really saying is “I am bored and have nothing to read, will you share?”. You’d be surprised at the conversations that ensue.
One of the articles covered new features in the Linux 2.6 kernel, including the EXPORT_SYMBOL_GPL() macro for use in loadable modules. The macro allows a module to hide it’s API from any module that does not use a GPL-compatible license.
What a great way to punish developers who write Linux software but don’t (or can’t) GPL their work. It’s like a declarative digital rights management system that, like most DRM schemes, inflicts most of it's pain on innocent bystanders.
My latest article: Master Pages In ASP.NET 2.0. Excerpt:
The master page implementation outlined above has another consequence to watch for. Since the master page injects it's controls and markup into a page’s Controls array, any relative URLs in the master page markup may break. Remember, the browser will request the web form, not the master page, so all of the URLs will be relative to the web form. When the web form and master page are in different directories, relative URLs may point to the wrong location. To help alleviate relative URL problems, ASP.NET will rebase relative URLs for server-side controls. Rebasing will build the correct URL to the resource.
P.S. Every tool ever made to format code into HTML has at least one problem that drives me insane.
There is a subtle difference in the default ASP.NET 2.0 ASPX files for VB and C#. I mention the difference only because C# is traditionally the ‘explicit’ language while VB.NET is the language with late binding features built-in.
A new VB.NET web form places AutoEventWireup=”false” in it’s @ Page directive. This means your code is responsible for explicitly wiring up Page events.
A new C# web form places AutoEventWireup=”true” in it’s @Page directive. This means the runtime will reflect upon your code to find method names in the form of Page_EventName and attach the methods as event handlers for named event.
Why is this?
VB.NET’s Handles keyword allows you to catch an event in a declarative manner. There is no comparable feature in C#. It’s a nice feature to have.
Here is something nice that comes from the new compilation model in ASP.NET 2.0. Let’s say you add a custom property to a master page code-behind file like so:
Partial Class otcMaster Inherits System.Web.UI.MasterPage Public Property FooterText() As String Get Return Footer.Text End Get Set(ByVal value As String) Footer.Text = value End Set End Property End Class
You can get to the master page for a web form using the inherited Master property, which returns a MasterPage reference. To get to a property defined in otcMasterPage though, you might think you need to use a cast.
CType(Master, otcMaster).FooterText ="foo"
Casting to a derived type is just a part of life when using frameworks and statically typed languages, but there is a better way. Use the @ MasterType directive in the ASPX.
<%@ MasterType VirtualPath="~/otc.master" %>
Now when ASP.NET codegens the page, it puts the following inside a partial class definition. Notice the Shadows keyword (that would be the new keyword in semicolon land [yeah, I’m experimenting with alternative languages]).
Public Shadows ReadOnly Property Master() As otc Get Return CType(MyBase.Master,otcMaster) End Get End Property
The result is a strongly typed Master Page. We don’t need a cast, we can go right to the Master.FooterText property. Another way to do this is to specify a TypeName in the @MasterType directive.
This weekend I’m playing in the pit orchestra for a community theater production of Sondheim’s Tony winner “Into The Woods”. The musical is a funny blend of fairy tales into a story of love, lust, and death by angry giant. I enjoy the music and storytelling in this show. My only criticism is the blatant use of a deus ex machina near the end.
Some of my favorite quotes:
Cinderella: Opportunity is not a lengthy visitor.
Cinderella’s prince: I was raised to be charming, not sincere.
Rapunzel’s prince: Dwarves are very upsetting.
Jack’s Mother: Children can be very queer about their animals.
Witch: I'm not good, I'm not nice, I'm just right.
I'm the Witch.
You're the world.