namrata 的个人资料Nasha照片日志列表更多 工具 帮助

日志


1月27日

Article : Access Win Registry through .NET

Registry has been a central repository for a lot of Microsoft applications over the years. You can access a machine's registry using the regedit tool. . NET also provides us with classes named RegistryKey and Registry under Microsoft.Win32 namespace to access registry.

Registry class exposes all the main key of the registry i.e. CurrentUser, CurrentConfig, LocalMachine, CurrentConfig, ClassesRoot and Users as Registry.CurrentUser, Registry.CurrentConfig, Registry.LocalMachine, Registry.CurrentConfig, Registry.ClassesRoot and Registry.Users.

There are methods to get any sub key under any of the main keys (the ones mentioned above).

You can retrieve reference to the main and then retrieve the list of sub keys under it.

E.g. Here I am retrieving reference to the registry key CurrentUser and then retrieve the list of sub keys under it.

RegistryKey rk = Registry.CurrentUser.OpenSubKey("Software");

string[] keys = rk.GetSubKeyNames(); // returns an array of sub key names.

Note: In the above code retrieving a reference to the Current User Registry Key returns me an Registry Key object. To retrieve any detail of that registry key I need to call methods registry key object.

You can retrieve the sub key count calling the SubKeyCount () method on registry key object.

To create a sub key under any registry key retrieve the reference to that registry key and call CreateSubKey() method.

E.g. Here I am creating a sub key named "Nasha" under the Root\CurrentUser\Software.

RegistryKey rk = Registry.CurrentUser.OpenSubKey("Software",true);

RegistryKey subkey = rk.CreateSubKey("Nasha");

Remember whenever you open a key to create keys under it pass the second value as true. Passing the second value as true will grant you a write access. CreateSubkey method returns reference to the new key. Thus you can use this reference to create nested keys.

To create values under that key node call the Setvalue() method and pass the name and value parameters.

rk.SetValue("abcd","abcd");

To delete keys and values there are methods like DeleteSubKey(), DeleteSubKeyTree(), DeleteValue().

There are a lot of other useful methods like

GetValueNames() and GetSubKeyNames() and properties like rk.ValueCount and rk.SubKeyCount.

After you are through with your manipulation dont forget to close the key with

rk.Close();

1月24日

Locking config setting using <location> tag

Hi Group,
 
In ASP.NET is very easy to override configuration settings defined in the machine.config. All that you need to do is create a web.config file and specify the settings in it. Sometimes we want that certain configuration settings are not overridden by any application esp if it is your company server hosting many applications.In that case we need to lock these settings.
 
There is a tag called <location> tag which can be added to machine.config file. This tag has two attributes named path which is the path of the application and allowOverride which takea a boolean value. If we set the value of allowOverride attribute as false then if the application mentioned in the path tries to override config settings will get an error.
 
e.g.
 <configuration>
     <location path="DefaultwebsitePath/MyApp" allowOverride="true">
         <system.web>
          |
          | Session state settings, trace settings etc
          |
         </system.web>
      </location>
 </configuration>
 
Now if MyApp tries to overrider these settings it will get an error.
 

-- Please post your queries and comments for my articles in the user group for the benefit of all. I hope this step from my end is helpful to all of us. You can find all articles written by me at my personal blog http://spaces.msn.com/members/nasha.

Regards,

Namratha (Nasha)   

1月20日

Configuring machine.config to recycle aspnet_wp

There has been a lot of times when we feel that our application is slowing down or the ASP.Net worker process is not working as its best. Although ASP.NET does recycle its process after certain number of requests or memory Limit but there are times when you feel that you could control these parameters and explicitly restart the worker process.

It is possible to restart the worker process explicitly after a certain number of requests.

In Machine.config under <configuration> <system.web><procesmodel> we have an attribute called requestLimit.

Set this request Limit to the number of requests after you want to recycle your worker process. It can be set to Infinite or any particular number. The default setting is 5000.

Suppose if we set to it say 10 then you will notice that after every 10 requests aspnet_wp process will be recycled. You can note the process id's to feel the change.

Second reason coz of which we may want our process to be recycled is because of high consumption of memory.

In Machine.config under <configuration> <system.web><procesmodel> we have an attribute called memoryLimit. Set the threshold to the amount you want. The default is 60 i.e. 60%. The moment this threshold is reached aspnet_wp will be recycled.

Before we make any changes to the machine.config we must remember that these changes are going to affect all the applications on that machine coz we are these changes at the core level. Hence after making these changes we should bench mark all our applications.

1月16日

Overriding, Shadowing and Hiding in .NET

Most of us I guess are familiar with overridering from C++ or Java. Overriding as the term says is to override  the base class  implementation  or provide a new  implementation in the derived class. We can override members in the base class in VB.Net using  the keyword Overrides and in C# using the key word override. To override a base class member in VB.Net it should be marked as  Overridable and in C# they should be marked with virtual. Method signature of the overiddden methods should be same as the base  class methods.

Shadowing :- This is a VB.Net Concept by which you can provide a new implementation for the base class member without overriding  the member. You can shadow a base class member in the derived class by using the keyword "Shadows". The method  signature,access level and return type of the shadowed member can be completely different than the base class member.

Hiding : - This is a C# Concept by which you can provide a new implementation for the base class member without overriding the  member. You can hide a base class member in the derived class by using the keyword "new". The method signature,access level and  return type of the hidden member has to be same as the base class member.

Comparing the three :-

1) The access level , signature and the return type can only be changed when you are shadowing with VB.NET. Hiding and overriding  demands the these parameters as same.

2) The difference lies when you call the derived class object with a base class variable.In class of overriding although you assign a  derived class object to base class variable it will call the derived class function. In case of shadowing or hiding the base class function  will be called.

Let us create a sample application and this check out :-

1) Create a new solution and three projects to it. One VB.Net Class Library, another C# Class Library and C# Console Application as  a Client Application.

2) Name your VB.Net Class Library as Shadowing , C# library as Hiding and Your console application as Client Application.

3) In Shadowing add a class file called Shadow.vb and add the following classes to it.

Public Class BaseShadow

    Public Overridable Function OverrideMe() As String
        Return "Base Class Override Me"
    End Function

    Public Function ShadowMe() As String
        Return "Base Class Shadow Me"
    End Function

End Class


Public Class DerivedShadow
    Inherits BaseShadow

    Public Overrides Function OverrideMe() As String
        Return "Derived Class Override Me"
    End Function

    Public Shadows Function ShadowMe() As String
        Return "Derived Class Shadow Me"
    End Function

End Class

4) In Hiding add class file called Hide.cs and add the following classes to it.

using System;

namespace Hiding
{
        public class BaseHide
        {
                public BaseHide()
                {

                }

                public virtual string OverrideMe()
                {
                        return "Base Class Override Me";
                }

                public string HideMe()
                {
                        return "Base Class Hide Me";
                }

        }

        public class DerivedHide:BaseHide
        {
                public DerivedHide()
                {

                }
                public override string OverrideMe()
                {
                        return "Derived Class Override Me";
                }

                public new string HideMe()
                {
                        return "Derived Class Hide Me";
                }

        }
}

5) Build both the Class Libs and add their refernces to the client console application.

6) Add the following code in the Main of the console Application.

using System;
using Hiding;
using Shadowing;
       
namespace Client_Application
{
        /// <summary>
        /// Summary description for Class1.
        /// </summary>
        class Client
        {
                /// <summary>
                /// The main entry point for the application.
                /// </summary>
                [STAThread]
                static void Main(string[] args)
                {

                        Console.WriteLine("// ****  Overriding **** //");
                        // ****  Overriding **** //

                        Shadowing.DerivedShadow derivedShadowOverrideObject = new Shadowing.DerivedShadow();
                        Console.WriteLine("Accessing thru derived class " + derivedShadowOverrideObject.OverrideMe());

                        Shadowing.BaseShadow baseShadowOverrideObject = new Shadowing.DerivedShadow();
                        Console.WriteLine("Accessing thru base class " + baseShadowOverrideObject.OverrideMe());

                        Hiding.DerivedHide derivedHideOverrideObject = new Hiding.DerivedHide();
                        Console.WriteLine("Accessing thru derived class " + derivedHideOverrideObject.OverrideMe());

                        Hiding.BaseHide baseHideOverrideObject = new Hiding.DerivedHide();
                        Console.WriteLine("Accessing thru base class " + baseHideOverrideObject.OverrideMe());


                        // ****  Hiding **** //

                        Console.WriteLine("// ****  Hiding **** //");
               
                        Hiding.DerivedHide derivedHideObject = new Hiding.DerivedHide();
                        Console.WriteLine("Accessing thru derived class " + derivedHideObject.HideMe());
                       
                        Hiding.BaseHide baseHideObject = new Hiding.DerivedHide();
                        Console.WriteLine("Accessing thru base class " + baseHideObject.HideMe());

                        // ****  Shadowing **** //

                        Console.WriteLine("// ****  Shadowing **** //");

                        Shadowing.DerivedShadow derivedShadowObject = new Shadowing.DerivedShadow();
                        Console.WriteLine("Accessing thru derived class " + derivedShadowObject.ShadowMe());

                        Shadowing.BaseShadow baseShadowObject = new Shadowing.DerivedShadow();
                        Console.WriteLine("Accessing thru base class " + baseShadowObject.ShadowMe());

                        Console.ReadLine();
                }
        }
}

7) Execute the code and checkout the differences. You can even go ahead and change the method signature, accesslevel and return type for Shadowing and check it out.

12月11日

Volatile" C# Keyword

C# has a keyword named  "volatile".  This keyword is used to mark a particular object "volatile" . i.e. the value of this object can change any time in the program by any other thread or process and thus the system always reads the current value of such an object as the value of this object will never be cached.

This modifier is generally used if there are multiple threads using the same object without using the "lock" keyword. Using the volatile modifier ensures that all threads retrieve the latest value of the object.

Using volatile key word does not solve the thread synchronization problem.

Objects which can be marked volatile can be :

  • Any reference type.
  • Any pointer type (in an unsafe context).
  • Datatypes like sbyte, byte, short, ushort, int, uint, char, float, bool.
  • An enum type with an enum base type of byte, sbyte, short, ushort, int, or uint.

User defined conversions using "implicit" and "explicit" keywords

C# allows you to declare user defined conversions on classes or structs so that classes or structs can be converted to the other type easily. Conversions can be declared either as implicit, which occur automatically when required using the "implicit" keyword, or they occur explicitly using the "explicit" key word which require an explicit casting (i.e. type casting) of the object.

All methods which define conversions must be static.

Check out this example :

1. Create a console application.

2. Add this code given below.

3. Checkout the conversion functions i.e. the conversions of MyNameclass to int and string.

4. Currently the conversion to string and int is "implicit" and hence we have not typed casted the conversion of MyNameclass to string and int in the Main.

5. Compile the program and check the output.The out put should be "Namratha H Shah" and "13".

Code :

public class MyNameclass

{

private string FirstName =null;

private string Initial =null;

private string LastName =null;

public MyNameclass()

{

FirstName ="Namratha";

Initial ="H";

LastName ="Shah";

}

static public implicit operator string(MyNameclass o)

{

return o.FirstName + " " + o.Initial + " " + o.LastName;

}

static public implicit operator int(MyNameclass o)

{

return o.FirstName.Length + o.Initial.Length + o.LastName.Length;

}

 

public static void Main()

{

string s = new MyNameclass();

int i = new MyNameclass();

Console.WriteLine(s);

Console.WriteLine(i);

Console.ReadLine();

}

}

6. Replace the implicit keyword with explicit and then compile ... the program will not compile unless you explicitly type cast as follows :

string s = (string) new MyNameclass();

int i = (int) new MyNameclass();

7.Make the changes and recompile and execute the program.

Multiple Indexers In a Class using Interface Indexers

We all know about class indexers. Well you can also have indexers in interfaces.
 
Interface indexers differ from class indexers in the following ways :-
 
  • Interface accessors do not use modifiers.
  • An interface accessor does not have a body.
  • The purpose of the accessor is to indicate whether the indexer is read-write, read-only, or write-only.
 
The following is an example of an interface indexer:
 
1. Open a new console project.
2. Create two interfaces i.e. Interface1 and Interface2 (as shown below in the code).
3. Implement the indexer in each of the interfaces as shown below.
3. Create a class called as MyClass(as shown below) which implements these two Interfaces.
 
 
Code :
class MyClass:Interface1,Interface2
 {
  private int[] ArrayofStrings=new int[100];
  public MyClass()
  {
   
  }
 
  public int this[int index] // Interface1
  {
   get
   {
    return ArrayofStrings[index];
   }
   set
   {
    ArrayofStrings[index]=value;
   }
  }
  
  string Interface2.this[int index]
  {
   get
   {
    return ArrayofStrings[index].ToString() + " String";
   }   
  }
 }
 
 public class MainClass
 {
  public static void Main()
  {
   MyClass o = new MyClass();

   o[1] = 1; // interface1

   Console.WriteLine(((Interface2)o)[1].ToString());  // Interface2

   Console.ReadLine();
  }
 }
 
 
 public interface Interface1
 {
  int this[int index]
  {
   get;
   set;
  }       
 }

 public interface Interface2
 {
  string this[int index]
  {
   get;
  }
 }
You will notice that this class has two indexers one coming from the Interface1 and other coming from Interface2. Indexer function for Interface1 has the access modifier as "public" whilst the indexer for Interface2 is private.
Since the access modifier for indexer of Inferface1 is public you can access it directly from the main as you would have accessed any other class indexer.
 
But you will notice that along with indexer for Interface1 you can also access the indexer for interface2 by type casting because the Interface2 is public.
 
Hence in this way you can have multiple indexers in a class using Interface Indexers.

Conditional Methods using Conditional Attribute

Conditional Attribute is defined in System.Diagnostics namespace.

When a conditional method is called its call is determined by the presence or absence of the preprocessor symbol used with the conditional attribute. If this preprocessor symbol is defined then the mehotd call is included else omitted.

Using conditional attibute is an alternative to calling methods in #if & #endif preprocessors.

A method can have multiple conditional attributes. The call to such a method is made if at least one of the conditional symbols is defined.

A conditional method has a few constraints:

  • A conditional method must be a method in a class or struct declaration and should not have any return type ... i.e. the return type should be "void".
  • The conditional method must be a method in a class or struct declaration a compile-time error occurs if the Conditional attribute is specified on a method in an interface declaration.
  • Conditional methods cannot be marked with override keyword.
  • Conditional methods can be virtual and the methods which override such a conditional method implicitly becomes Conditional
  • Methods defined in an interface cannot be marked as conditional.

Example

Step :

1. Create a new Console Application and define 2 classes MyClass and MyClient.

2. In MyClass define two as shown below.

class MyClass

{

[Conditional("CON_Attrib1")]

public void MyFun1(string name)

{

Console.WriteLine(name);

}

[Conditional("CON_Attrib1"),Conditional("CON_Attrib2")]

public virtual void MyFun2(string name)

{

Console.WriteLine(name);

}

}

3. In MyClient write the preprocessor directives as shown . (They should be the first two lines in the file... above using System ... if not it will not compile)

#define CON_Attrib1

#define CON_Attrib2

4. Call the My Class methods from the main as shown

public class MyClient

{

public MyClient()

{

}

public static void Main()

{

MultiFile1.MyClass oMyClass = new MyClass();

oMyClass.MyFun1("Namratha");

oMyClass.MyFun2("Nasha");

Console.ReadLine();

}

}

4. Build the solution and run . You will see both "Namratha" & "Nasha" ... i.e both the functions were called.

5. Now change the #define CON_Attrib1 to #undef CON_Attrib1. ... i.e. undefining the attribute.

6. Build the solution and run . You will see only "Nasha" ... i.e MyFun1 was not called as the preprocosser directive "CON_Attrib1" is not defined. But MyFun2 is called coz the other preprocessor directive "CON_Attrib2" is defined. When there are moer than one directives it an OR condition hence if any of the preprocessor directive is define the function will be called.

7. MyFun2 is marked as virtual hence if another function overrides its then is becomes conditional implicitly.

How to create a multifile assembly using ".netmodules" ?

Lot of us have been asked this quetion in our interviews. So here are the steps to create a multifile assembly using ".netmodules" .

Step 1:

1.      Create a console application Named MultiFile1.

2.      Add a class to this application named MyClass.

3.      Remove the "Main" method from the class.

4.      Add a new method to the class named "MultiFile1_Method"

5.      Go to the visual studio command prompt, go to the directory where this class resides.

6.      Compile the class with this command : csc /t:module MyClass.cs

7.      This is will create a file with extension ".netmodule" named MyClass.netmodule.

 

Code :

 

using System;

namespace MultiFile1
{
 class MyClass
 {
 public void MultiFile1_Method()
  {
   Console.WriteLine("This is a method from MultiFile1");
   Console.ReadLine();
  }
 }
}

 

 


Step 2: 
    1. Add another class to the project named MyClient.cs
    2. Change the namespace of the class from "Multifile1" to "MultiFile2"
    3. Add the reference to the "MultiFile1" namespace.
    4. Add the main method to the class.
    5. Call the method "MultiFile1_Method" of Myclass in the Main.
    6. Go to the visual studio command prompt, go to the directory where this class resides.
    7. Compile the class with this command : csc /addmodule:MyClass.netmodule /t:module MyClient.cs
    8. This is will create a file with extension ".netmodule" named MyClient.netmodule.   
        Code :
 
using System;
using MultiFile1;
 
namespace MultiFile2
{
 
 public class MyClient
 {
  public MyClient()
  {
  }
  public static void Main()
  {
   MultiFile1.MyClass oMyClass = new MyClass();
   oMyClass.MultiFile1_Method();
  }
 }
}

Step 3:

 

1.      Go to the visual studio command prompt, go to the directory where these classes reside

2.    Create the assembly with the following command :

                    al MyClass.netmodule MyClient.netmodule /main:MultiFile2.MyClient.Main /out:MyAssembly.exe /target:exe<o:p></o:p>

3.    MyAssembly.exe will be created.

<o:p>4.   O</o:p>pen the exe with ildasm and you will refernces to the two .netmodules that we created .

 

 

MyAssembly opened in ildasm :

 

.module extern MyClient.netmodule
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
  .hash = (E6 8E F4 00 2B 3C 3C 88 D6 32 F2 72 A3 22 FA C8   // ....+<<..2.r."..
           A7 7B 24 07 )                                     // .{$.
  .ver 1:0:5000:0
}
.assembly MyAssembly
{
  // --- The following custom attribute is added automatically, do not uncomment -------
  //  .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(bool,
  //                                                                                bool) = ( 01 00 00 01 00 00 )
  .hash algorithm 0x00008004
  .ver 0:0:0:0
}
.file MyClass.netmodule
    .hash = (92 EC 2F E8 F2 90 4B 2D 54 C6 AC 4C C5 69 CF 92   // ../...K-T..L.i..
             37 2B A1 2F )                                     // 7+./
.file MyClient.netmodule
    .hash = (7B 4E 77 76 94 24 D9 3D 26 B4 3C 98 BA B1 49 3E   // {Nwv.$.=&.<...I>
             9C 45 90 0A )                                     // .E..
.class extern public MultiFile2.MyClient
{
  .file MyClient.netmodule
  .class 0x02000002
}
.module MyAssembly.exe
// MVID: {0B92C2A4-6956-4ED7-A40D-BAB2D6C505D4}
.imagebase 0x00400000
.subsystem 0x00000003
.file alignment 512
.corflags 0x00000001
// Image base: 0x071f0000

3 steps to Late binding in VB.Net and C# ... Check it out

 
Nice to know that you guys are appreciating my effort. I have got a lot of replies for my article on "Differences between Vb.Net and C#". One of the difference between them is the way Vb.Net and C# handles late binding which is very interesting. I have got some mails requesting to go in more detail for the same.
 
Here it is !!!!
 
This is a code snippet showing how to achieve late binding in both Vb.Net and C# .
 
Step One :
        Create a Dll called Calc.dll which has a class named MyClass. 
        Add a function called "Add" which adds two number and returns the result. The implementaion for it is as follows :
 
namespace Calc
{
 public class MyClass
 {
  public MyClass()
  {
  }
  public int Add (int i , int j)
  {
   return i+j;  // adds the two numbers and returns the result
  }
 }
}

 
 
 
Step Two :
 
    Create a Vb.Net project (may be Windows Application project) which can use the above Dll.
    Add reference to the above Dll.
    Add a button to the form and type and code as shown below
 
 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim oMyClass As Object
        oMyClass = New Calc.MyClass
        MessageBox.Show(oMyClass.Add(1, 2))     
 End Sub
 
    Please take not that in the above code.The Type of "oMyClass" object is Object and NOT Calc. But the complier will still complie this code. (Check the intellisense for oMyClass object and the you will not see the Add method instead you will see the default methods of type Sysem.Object)
 
 
Step Three :
 
    Create a C#.Net project (may be Windows Application project).
    Dont add reference to the above Dll.
    Add two buttons to the form and type and code as shown below:
 
    Button 1:
 
    Assembly oAssembly = Assembly.LoadFrom("Calc.dll");
    Type[] oTypes = oAssembly.GetTypes();
 
   foreach(Type oTempType in oTypes)
   {
    MethodInfo[] mi = oTempType.GetMethods(BindingFlags.DeclaredOnly|BindingFlags.Public|BindingFlags.Instance );
    Object oLateBoundObject = Activator.CreateInstance(oTempType);    
    MessageBox.Show(mi[0].Invoke(oLateBoundObject,new object[]{1,2}).ToString()); // Calling the Add Method
   }
 
Please take a note that the way C# handles late biding is completely different and is based on Reflection.
 
    Button 2:
 
    /*
        THIS CODE WILL NOT COMPILE
      
        Object oMyClass = new Object();
        oMyClass = new DLLProj.MyClass();
        MessageBox.Show(oMyClass.Add(1, 2).ToString());
   
   */
 
    Well if we try to do it the way we did in VB.Net it will simply just not compile. Uncomment the code for Button 2 and check it out for urself.

Working with pointers in C# !!!!

Yesterday I had posted the differences between C# and Vb.Net. One of the differences between C# and Vb.Net is (checkout the article before reading ahead) that in C# you can have unmanaged code whilst in VB.Net. I happen one of those developers who use to love pointers rite from the good old 'C' days.
 
Here are the steps to create a simple unmanaged code in C# (as you would have done in C\C++)
 
1. Create a new console application.
2. Create an empty class  e.g. UnManagedCode.cs,
3. Create a static void Main function. (C or C++ style)
4. Create a another function named funWithPointers in the class to be called from Main.
6. Type in the code as shown in the snippet below.
7. Go to you Project Properties .. Configuration Properties ...Set Allow Unsafe Code Blocks to true by default it is false.
8. F5
 
 
Code snippet
 
using System;
 
namespace PointersinCSharp
{
 public class UnManagedCode
 {
  unsafe void funWithPointers()
  {
   Console.WriteLine("This is demo for unmanaged code");   
   int i = 100;
   int *p = &i;
   Console.WriteLine("\n" + "The value of p is =" + *p);
   Console.ReadLine();
  }
  static void Main()
  {
   UnManagedCode objUnManagedCode = new UnManagedCode();
   objUnManagedCode.funWithPointers();
  }
 } 
}

 
So now you can have both managed and unmanaged code in C#. Have fun with pointers !!!!

What should I user VB.NEt or C#? Which is the best ?

 
This is the question which all of us have in our minds. I happen to read through a white paper and thought should share this information with all of u.
 
Because of the previous differences between Visual Basic and C/C++, many developers assume incorrectly about the capabilities of Visual Basic .NET. Many Visual Basic developers think that Visual C# is a more powerful language than Visual Basic. In other words, Visual Basic developers assume that you can do many things in Visual C# that you cannot do in Visual Basic .NET, just as there are many things that you can do in C/C++ but cannot do in Microsoft Visual Basic 6.0 or earlier. This assumption is incorrect.
 
Although there are differences between Visual Basic .NET and Visual C# .NET, both are first-class programming languages that are based on the Microsoft .NET Framework, and they are equally powerful. Visual Basic .NET is a true object-oriented programming language that includes new and improved features such as inheritance, polymorphism, interfaces, and overloading. Both Visual Basic .NET and Visual C# .NET use the common language runtime. There are almost no performance issues between Visual Basic .NET and Visual C# .NET. Visual C# .NET may have a few more "power" features such as handling unmanaged code, and Visual Basic .NET may be skewed a little toward ease of use by providing features such as late binding. However, the differences between Visual Basic .NET and Visual C# .NET are very small compared to what they were in earlier versions.
 
The "Differences Between Microsoft Visual Basic .NET and Microsoft Visual C# .NET" white paper describes some of the differences between Visual Basic .NET and Visual C# .NET. However, remember that the .NET Framework is intended to be language independent. When you must select between Visual Basic .NET and Visual C# .NET, decide primarily based on what you already know and what you are comfortable with. It is easier for Visual Basic 6.0 developers to use Visual Basic .NET and for C++/Java programmers to use Visual C# .NET. The existing experience of a programmer far outweighs the small differences between the two languages.
 
No matter which language you select based on your personal preference and past experience, both languages are powerful developer tools and first-class programming languages that share the common language runtime in the .NET Framework.
 

P.S. This is an extract from the "Differences Between Microsoft Visual Basic .NET and Microsoft Visual C# .NET" white paper. You can download the whitepaper from the this link http://download.microsoft.com/download/VisualStudioNET/document/1.0/WIN98MeXP/EN-US/VBCSharpWp.exe.

Wonder why C# does not have an option of "Optional Paramaters"

Wonder why C# does not have an option of "Optional Paramaters"
 
Well we all know that C# does not have an option of creating optional paramters in our methods whilst VB.NET does support. Well when we are creating methods with optional parameters in VB.NET internally the CLR is creating an overlaod  of the same. The CLR is implementing that overload for you. This is advantageous to an extent as it saves your time since your job is been done by some one else ... the CLR.
 
On the other hand C# does not do that extra work for you and expects you to explicitly code for the overload.
 
C# developers keep working hard !!!!
 

Wonder why GC has only 2 generations

Wonder why GC has only 2 generations :

The CLR Garbage Collector is a generational, mark-and-compact collector. It follows several principles that allow it to achieve excellent performance. First, there is the notion that objects that are short-lived tend to be smaller and are accessed often. The GC divides the allocation graph into several sub-graphs, called generations, which allow it to spend as little time collecting as possible. Gen 0 contains young, frequently used objects. This also tends to be the smallest, and takes about 10 milliseconds to collect. Since the GC can ignore the other generations during this collection, it provides much higher performance. G1 and G2 are for larger, older objects and are collected less frequently. When a G1 collection occurs, G0 is also collected. A G2 collection is a full collection, and is the only time the GC traverses the entire graph. It also makes intelligent use of the CPU caches, which can tune the memory subsystem for the specific processor on which it runs. This is an optimization not easily available in native allocation, and can help your application improve performance.

What Happens When a Collection Occurs?

Let's walk through the steps a garbage collector takes during a collection. The GC maintains a list of roots, which point into the GC heap. If an object is live, there is a root to its location in the heap. Objects in the heap can also point to each other. This graph of pointers is what the GC must search through to free up space. The order of events is as follows:

  1. The managed heap keeps all of its allocation space in a contiguous block, and when this block is smaller than the amount requested, the GC is called.
  2. The GC follows each root and all the pointers that follow, maintaining a list of the objects that are not reachable.
  3. Every object not reachable from any root is considered collectable, and is marked for collection.

  4. Removing objects from the reachability graph makes most objects collectable. However, some resources need to be handled specially. When you define an object, you have the option of writing a Dispose() method or a Finalize() method (or both). I'll talk about the differences between the two, and when to use them later.
  5. The final step in a collection is the compaction phase. All the objects that are in use are moved into a contiguous block, and all pointers and roots are updated.
  6. By compacting the live objects and updating the start address of the free space, the GC maintains that all free space is contiguous. If there is enough space to allocate the object, the GC returns control to the program. If not, it raises an OutOfmemoryException.