tags:

views:

72

answers:

3

We have Object and ValueType.... And String....

String is derived from object, but it is immutable. Is it considered a type of it's own as it doesn't behave like other objects? Is it the only object that has this immutable behaviour? Is it the runtime, compiler or library that defines this? And are there other cases like this in .Net?

Edit: Yes, I too create classes that isn't allowed to change after constructed; immutable objects. But isn't string more special than this?

A: 

String is a reference type (see here), but its behaviour is a bit special. As you say, it is immutable, and assignment copies the string content rather than the object's reference.

Regarding your question, of course string is a "separate" type. I am not sure what you mean by "separate", but each class and struct in .NET is a type of its own.

CesarGon
No, it copies the reference just like every other reference type.
Jon Skeet
@Jon: But if I do string a = "Hello"; string b = a; then any changes to a are not "seen" by b. Doesn't that mean that the content of the string is copied on assignment?
CesarGon
@CesarGon, no, it means that all strings are immutable - thus, it is impossible to change a.
hemp
@Jon, @hemp: I see it now. Thanks to both for clarifying.
CesarGon
a and b don't contain the string "Hello". They contain the number 68324, which is the place in memory where the string lives. If you then write `a = "Bob"`, a has the value 68700 while b still equals 68324.
Jonathan Allen
@Jonathan: Of course. I got it now.
CesarGon
+8  A: 

string is a reference type. There are plenty of other immutable types though, and you can create your own: just don't provide any members which change the state! Here's an example:

public class Int32Wrapper
{
    private readonly int value;
    public int Value { get { return value; } }

    public Int32Wrapper(int value)
    {
        this.value = value;
    }
}

Of course, string also overloads == and !=, overrides Equals and GetHashCode etc... all of which can be done in your own types too.

string does have some genuinely special properties though:

  • It's the only reference type for which there's a literal format in IL (and in supporting languages)
  • There are IL instructions which specifically use strings
  • Other than arrays, string is the only type where the size of the object which varies by instance. (Other types vary depending on the CLR you're using, but for any one CLR, all instances of other types will have the same size - strings and arrays vary by content.)
  • If you call new String(new char[0]) repeatedly, you'll get the same reference every time
  • It interacts with the interop marshaller in magical ways :)
Jon Skeet
So there is nothing special about string at all? I know the values are shared between instances, and this is perhaps a runtime thing. But it is not treated special in other cases? Not even for immutability?
simendsjo
He just laid out the ways in which it is special. All else is equal.
hemp
@hemp: Yes, after my comment. Remember that Jon Skeet can edit posts without even SO knowing about it.
simendsjo
@Jon: I've heard in the past that the JITter has special knowledge of strings and optimizes accordingly, if that's true, I'd say that's one more way where strings are "special". But perhaps that applies to any built-in type.
hemp
@simendsjo: I'm pretty sure my edit was there before your comment. Possibly not before you'd started writing your comment, admittedly. @hemp: I don't know about that. Possibly.
Jon Skeet
+3  A: 

The author of the class determines whether instances of the class are immutable.

Here's another immutable class: (a reference type, not a value type)

public class Person
{
    private readonly string name;
    private readonly int age;

    public Person(string name, int age)
    {
        this.name = name;
        this.age = age.
    }

    public string Name
    {
        get { return name; }
    }

    public int Age
    {
        get { return age; }
    }
}
Tim Robinson