Http://www.codeproject.com/KB/cs/csenums01.aspxIntroduction
Just about everything is a heap object when you are using C #. Only elementary native types likeInt
Are treated as value types. But there are two value types in C # That are pretty much more useful that first glances wocould tyou. They areEnum
AndStruct
Types. Very few tutorials even cover these topics, but they have their own uses. And both of them are a lot more efficientClassEs and you can use them in placeClassEs when they meet your requirements to improve performance.
Enum S
Enum S are basically a set of named constants. They are declared in C # using Enum
Keyword. Every Enum
Type automatically derives from System.Enum
And thus we can use System.Enum
Methods on our Enum S. Enum S are value types and are created on the stack and not on the heap. You don't have to use New
To create Enum
Type. Declaring Enum
Is a little like setting the members of an array as shown below.
Collapse | Copy code
EnumRating {poor, average, okay, good, excellent}
You can passEnumS to member functions just as if they were normal objects. And you can perform arithmetic onEnumS too. For example we can write two functions, one to increment ourEnum
And the other to decrement ourEnum
.
Collapse | Copy code
Rating incrementrating (rating R ){If(R = rating. Excellent)ReturnR;ElseReturnR + 1;} rating decrementrating (rating R ){If(R = rating. Poor)ReturnR;ElseReturnR-1 ;}
Both functions takeRating
Object as argument and return backRating
Object. Now we can simply call these functions from elsewhere.
Collapse | Copy code
For(Rating R1 = rating. Poor; R1 <rating. Excellent; R1 = incrementrating (R1) {console. writeline (R1);} console. writeline ();For(Rating r2 = rating. Excellent; r2> rating. Poor; r2 = decrementrating (R2) {console. writeline (R2 );}
And here is a sample code snippet showing how you can callSystem.Enum
Methods on ourEnumObject. We callGetnames
Method which retrieves an array of the names of the constants inEnumEration.
Collapse | Copy code
Foreach(StringSInRating. getnames (Typeof(Rating) console. writeline (s );
Where to use Enum S
Quite often we have situations whereClassMethod takes as an argument a custom option. Let's say we have some kind of File AccessClassAnd there is a file open method that has a parameter that might be one of read-mode, write-mode, read-write-mode, create-mode and append-mode. now you might think of adding five static member fields to yourClassFor these modes. Wrong approach! Declare and useEnumEration which is a whole lot more efficient and is better programming practice in my opinion.
Struct S
In C ++ Struct
Is just about the same as Class For all purposes failed T in the default access modifier for methods. In C # Struct
Are a pale puny version of Class
. I am not sure why this was done so, but perhaps they decided to have a clear distinction Struct S and Class Es. Here are some of the drastic areas where Class Es andStruct S differ in functionality.
-
- StructS are stack objects and however much you try you cannot create them on the heap
-
- StructS cannot inherit from otherStructS though they can derive from Interfaces
-
- You cannot declare a default conStructOr for
Struct
, Your conStructORS must have Parameters
- The conStructOr is called only if you create your
Struct
UsingNew
, If you simply declareStruct
Just as in declaring a native type likeInt
, You must explicitly set each member's value before you can useStruct
Collapse | Copy code
Struct Student: igrade { Public Int Maths; Public Int English; Public Int CSHARP; //Public member function Public Int Gettot (){ Return Maths + English + CSHARP ;}//We have a conStructOr that takes an int as argument Public Student ( Int Y) {maths = English = CSHARP = y ;} //This method is implemented because we derive //From the igrade Interface Public String Getgrade (){ If (Gettot ()> 240 )Return " Brilliant" ; If (Gettot ()> 140 ) Return " Passed" ; Return " Failed" ;}} Interface Igrade { String Getgrade ();}
Well, now let's take a look at how we can use ourStruct
.
Collapse | Copy code
Student S1 =NewStudent (); console. writeline (s1.gettot (); console. writeline (s1.getgrade ());//Output0Failed
Here the default conStructOr gets called. This is automatically implemented for us and we cannot have our own default parameter-less conStructOr. The default parameter-less conStructOr simply initializes all values to their zero-equivalents. This is why we get a 0 as the total.
Collapse | Copy code
Student S2; s2.maths = s2.english = s2.csharp =50; Console. writeline (s2.gettot (); console. writeline (s2.getgrade ());//Output150Passed
Because we haven'tused new, the conStructOr does not get called. of all the silly features this one must win the annual contest by a long way. I see no sane reason why this must be so. anyway you have to initialize all the member fields. if you comment out the line that does the initialization you will get a compiler error :-Use of unassigned local variable 's2'
Collapse | Copy code
Student S3 =NewStudent (90); Console. writeline (s3.gettot (); console. writeline (s3.getgrade ());//Output270Brilliant
This time we use our custom conStructOr that takesInt
As argument.
When to use Struct S
Because Struct S are value types they wocould be easier to handle and more efficient that Class Es. When you find that you are using Class Mostly for storing a set of values, you must replace those Class Es Struct S. When you declare arraysStruct S because they are created on the heap, efficiency again improves. Because if they were Class Es each Class Object wocould need to have memory allocated on the heap and their references wocould be stored. In fact lots Class Es within the. NET Framework are actually Struct S. For example System. Drawing. Point
Is actually Struct
And notClass
.