Sunday, November 20, 2005

A brief study on 'structure'

We are familiar with the concept of “structure”, and all of us must have used it many times. Most of the languages like C++, Java, VB, and of course C# and VB.NET support the concept of structure, how if we dig a little deep into this concept.

As we all know structure is a complex type, not like int or bool, but there are some more characteristics of a structure, let me explain with the context of dot net platform…..

1) Every structure is inherited from System.Object( like any class ), well, every structure is inherited from System.ValueType which inherits System.Object, hence every structure is inherited form Object.

2) Structure can not be inherited, they are like “sealed class”.

3) Structure instance are stored in the stack, and for this reason it doesn’t need any garbage collection. (well, there are exception of this rule, please read the last paragraph )

4) A structure can be boxed into a System.ValueType variable in addition to an Object variable.

5) As “Abstract” and “Virtual” are useless in case of structure(any value type ) hence can we write structure doesn’t support polymorphism ?? well I think NO, since we can do function overloading so it would be wrong to say it doesn’t support polymorphism at all.

In essence we can say that a structure is a complex type whose behavior can not extended ( the way we do it in case of class, I mean to say using inheritance we can not extend the behavior, but we can use the concept of “containment” in structure ) .

Okay .. so why do we need a structure at all when we had “class” .. because
structure has a very small footprint compare to class instance and faster in performance and no overhead of garbage collection.
There are certain situations where structure is a good candidate( compare to class ) if
1) we need a complex type and typically whose behavior doesn’t need to be extended.
2) there will be no boxing involved.


As we have mentioned above that structure doesn’t need garbage collection and we also know that structure supports “Containment” .. now what if we have a structure which contain a reference type, consider the following example …

public struct A
{
public int y;
public bool z;
}

public struct B
{
public A x;
public Book y; // Book is a class
}

In the above example structure B is contain structure A and class Book, hence when we will create an instance of “B” there will some memory allocation in the heap for the Book class instance, and when the instance of the structure B will go out of scope the memory allocated for y and z will be cleared ( from the stack ) at once, but the Book class instance will be destroyed by the garbage collection( this is an exception of characteristics 3 mentioned above ).

3 comments:

Richard Hsu said...

hi Neo,

In Standard C++, struct and class are not that different as in CLR languages [in C++, the only difference is in default visibility of members].

I know you have specially mentioned "with the context of dot net platform.." but I needed some excuse to comment, so I did :-)

As for structs in VB6, I am not sure if there is any struct keyword or statement, but there is a Type statement which is used to define data only "structure"s primarily used for Win32 API interop.

The struct story in CLR has been nicely narrated by you Neo. I just want to add that its generally recommended that structs shoud be immutable. See "Mutable types considered harmful" by Peter Gold [http://peter.golde.org/2003/10/13.html#a16]

Oh, I haven't coded C# or done much CLR programming lately but you got me thinking again. :-)

I miss being in India and especially being in Kolkata[net]. Above all, I miss full-time programming.

Neo said...

Hey Richard, good to hear from you .. how is life in Canada ? must be very cool -:),

well, excellent thoughts and comments.

I have gone thru Peter Gold's blog.. in deed a good post ... well I am kind of agree with Rico Mariani, well the problem was related to due to the for each loop. If we mix up immutable and mutable type( on other words reference and value type ), we will face such issues.

well, there was a simple solution of Peter Gold's problem... instead of doing a for each .. we could write the same thing in the following manner....
for( int i = 0; i < parts.Length(); i++ )
{
parts[ i ].ReleasePens();
}

with the above code there wouldn't have any issue. am I correct ?

btw: we all miss you badly, why don't you write in kolkatanet anymore ( take it as a complain from my side ) ? Please enlight us with your thoughts whenever you get time.

Neo

Richard Hsu said...

I used Peter Golde's reference because he is a credible person [he was part of the C# language design team]

But there are many other cases where a mutable struct will hit a road block. The following will not even compile:-

using System;

struct MutableType {
int _count;

public void IncrementCount() {
_count++;
}

public int Count {
get {
return _count;
}
set {
_count = value;
}
}
}

class TypeHolder {
MutableType _data = new MutableType();

public MutableType Data {
get {
return _data;
}
}
}

class Program {
static void Main() {
TypeHolder d50 = new TypeHolder();

d50.Data.Count = 100;
d50.Data.IncrementCount();
Console.WriteLine(d50.Data.Count);
d50.Data.IncrementCount();
Console.WriteLine(d50.Data.Count);
}
}

change the struct to a class and everything works.

Also structs can't be null, so you have to figure out a Zero state for the complex type that you are trying to design [look at SqlInt32 and friends].

I think PalB is waiting in the wings and I'll be interested to hear what he has to say. :-)

To tell you honestly, now that I don't have to write code for a living, I don't even want to think about class vs. struct etc., thats why I use Python now.