Search

The Online Encyclopedia and Dictionary

 
     
 

Encyclopedia

Dictionary

Quotes

 

C Sharp programming language

(Redirected from C Sharp)


C# (pronounced see-sharp) is an object-oriented programming language developed by Microsoft as part of their .NET initiative. Microsoft based C# on C++ and the Java programming language. C# was designed to balance power (the C++ influence) with rapid development (the Visual Basic, Delphi programming language, and Java influences). The language features allowing interoperation with subroutines written in other programming languages, including other .NET languages, Component Object Model (COM) based objects and C style APIs exported from DLLs.

Contents

Language features

C# is, in some sense, the programming language which most directly reflects the underlying .NET Framework on which all .NET programs run, and it depends strongly on this framework; there is no such thing as an unmanaged C# program. Its primitive datatypes are objects of the corresponding .NET types, it is garbage-collected, and many of its abstractions, such as its classes, interfaces, delegates, exceptions, and so on, expose explicit features of the .NET runtime.

Compared to C and C++, the language is restricted or enhanced in a number of ways, including but not limited to the following:

  • Raw pointers and unchecked arithmetic can only be used in a special unsafe mode. Most object access is done through safe references, which cannot be made invalid, and most arithmetic is checked for overflow.
  • Objects cannot be explicitly freed, but instead are garbage collected when no more references to them exist (although deallocation can be encouraged by destroying references). This prevents dangling references.
  • Destructors (see object lifetime) are not available. The closest equivalent is the Disposable interface, which, together with the using block construct, can enforce that an object's resources are promptly deallocated. Finalizers are also provided, but as in Java, these are not prompt.
  • As in Java, only single inheritance is available, but a class can implement any number of abstract interfaces. This functions mainly to simplify the runtime's implementation.
  • C# is more typesafe than C++. The only implicit conversions by default are safe conversions, such as widening of integers and conversion from a derived type to a base type. There are no implicit conversions between booleans and integers, between enumeration members and integers, no void pointers (although references to Object are similar), and any user-defined implicit conversion must be explicitly marked as such, unlike C++'s copy constructors.
  • Syntax for array declaration is different ("int[] a = new int[5]" instead of "int a[5]").
  • Enumeration members are placed in their own namespace.
  • C# has no templates, but C# 2.0 has generics.
  • Properties are available, which enable methods to be called using syntax that resembles data member access.
  • Full reflection is available.

Although C# is often considered similar to Java, there are also a number of notable differences with this language as well, including the following:

  • Java does not have properties, operator overloading, or allow attributes to be attached to types and members.
  • Java does not have an unsafe mode permitting native pointer manipulation and unchecked arithmetic.
  • Java has checked exceptions, while C# exceptions are unchecked, as in C++.
  • C# has goto and foreach control flow constructs not found in Java (An enhanced for loop similar to foreach was added in Java 5.0).
  • Java uses Javadoc-syntax comments to automatically generate documentation from source files. C# uses XML-based comments for this purpose.
  • C# adds support for indexers and delegates.

Code libraries

The .NET Framework is a class library which can be used from a .NET language to perform tasks from simple data representation and string manipulation to generating dynamic web pages (ASP.NET), XML parsing and reflection. The code is organized into a set of namespaces which group together classes with a similar function, e.g. System.Drawing for graphics, System.Collections for data structures and System.Windows.Forms for the Windows Forms system.

A further level of organisation is provided by the concept of an assembly. An assembly can be a single file or multiple files linked together (through al.exe) which may contain many namespaces and objects. Programs needing classes to perform a particular function might reference assemblies such as System.Drawing.dll and System.Windows.Forms.dll as well as the core library (known as mscorlib.dll in Microsoft's implementation).

Hello world example

Here is a very simple C# program:

public class ExampleClass
{
    public static void Main()
    {
        System.Console.WriteLine("Hello world!");
    }
}

The effect is to write the text Hello world! to the output console. Let's break down each element:

public class ExampleClass

This is a class definition. It is public, meaning objects in other projects can freely use this class. All the information between the following braces describes this class.

public static void Main()

This is the entry point where the program begins execution. It could be called from other code using the syntax ExampleClass.Main(). Don't worry about the public static void part for now.

System.Console.WriteLine("Hello world!");

Here's where the action happens. Console is a system object, representing a command-line console where a program can input and output text. We are calling the Console method WriteLine, which causes the string passed to it to be displayed on the console.

Random String Example

The following code generates a random string.

using System;
using System.Security.Cryptography;

namespace RandomString
{
   public class RndStr
   {
      private static int DEFAULT_MIN_PASSWORD_LENGTH  = 8;
      private static int DEFAULT_MAX_PASSWORD_LENGTH  = 10;
      private static string PASSWORD_CHARS_LCASE  = "abcdefgijkmnopqrstwxyz";
      private static string PASSWORD_CHARS_UCASE  = "ABCDEFGHJKLMNPQRSTWXYZ";
      private static string PASSWORD_CHARS_NUMERIC= "23456789";

      public static string Generate()
      {
         return Generate(DEFAULT_MIN_PASSWORD_LENGTH, 
                         DEFAULT_MAX_PASSWORD_LENGTH);
      }

      public static string Generate(int length)
      {
         return Generate(length, length);
      }

      public static string Generate(int minLength, int maxLength)
      {
         // Make sure that input parameters are valid.
         if (minLength <= 0 || maxLength <= 0 || minLength > maxLength)
            return null;
         char[][] charGroups = new char[][] 
         {
            PASSWORD_CHARS_LCASE.ToCharArray(),
            PASSWORD_CHARS_UCASE.ToCharArray(),
            PASSWORD_CHARS_NUMERIC.ToCharArray()
         };

         // Use this array to track the number of unused characters in each
         // character group.
         int[] charsLeftInGroup = new int[charGroups.Length];

         // Initially, all characters in each group are not used.
         for (int i=0; i<charsLeftInGroup.Length; i++)
            charsLeftInGroup[i] = charGroups[i].Length;
        
         // Use this array to track (iterate through) unused character groups.
         int[] leftGroupsOrder = new int[charGroups.Length];

         // Initially, all character groups are not used.
         for (int i=0; i<leftGroupsOrder.Length; i++)
            leftGroupsOrder[i] = i;

         // Because we cannot use the default randomizer, which is based on the
         // current time (it will produce the same "random" number within a
         // second), we will use a random number generator to seed the
         // randomizer.
        
         // Use a 4-byte array to fill it with random bytes and convert it then
         // to an integer value.
         byte[] randomBytes = new byte[4];

         // Generate 4 random bytes.
         RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
         rng.GetBytes(randomBytes);

         // Convert 4 bytes into a 32-bit integer value.
         int seed = (randomBytes[0] & 0x7f) << 24 |
                     randomBytes[1]         << 16 |
                     randomBytes[2]         <<  8 |
                     randomBytes[3];

         // Now, this is real randomization.
         Random  random  = new Random(seed);

         // This array will hold password characters.
         char[] password = null;

         // Allocate appropriate memory for the password.
         if (minLength < maxLength)
            password = new char[random.Next(minLength, maxLength+1)];
         else
            password = new char[minLength];

         // Index of the next character to be added to password.
         int nextCharIdx;
        
         // Index of the next character group to be processed.
         int nextGroupIdx;

         // Index which will be used to track not processed character groups.
         int nextLeftGroupsOrderIdx;
        
         // Index of the last non-processed character in a group.
         int lastCharIdx;

         // Index of the last non-processed group. Initially, we will skip
         // special characters.
         int lastLeftGroupsOrderIdx = leftGroupsOrder.Length - 1;
        
         // Generate password characters one at a time.
         for (int i=0; i<password.Length; i++)
         {
            // If only one character group remained unprocessed, process it;
            // otherwise, pick a random character group from the unprocessed
            // group list.
            if (lastLeftGroupsOrderIdx == 0)
               nextLeftGroupsOrderIdx = 0;
            else
               nextLeftGroupsOrderIdx = random.Next(0, lastLeftGroupsOrderIdx);

            // Get the actual index of the character group, from which we will
            // pick the next character.
            nextGroupIdx = leftGroupsOrder[nextLeftGroupsOrderIdx];

            // Get the index of the last unprocessed characters in this group.
            lastCharIdx = charsLeftInGroup[nextGroupIdx] - 1;
            
            // If only one unprocessed character is left, pick it; otherwise,
            // get a random character from the unused character list.
            if (lastCharIdx == 0)
               nextCharIdx = 0;
            else
               nextCharIdx = random.Next(0, lastCharIdx+1);

            // Add this character to the password.
            password[i] = charGroups[nextGroupIdx][nextCharIdx];
            
            // If we processed the last character in this group, start over.
            if (lastCharIdx == 0)
               charsLeftInGroup[nextGroupIdx] = charGroups[nextGroupIdx].Length;
            // There are more unprocessed characters left.
            else
            {
               // Swap processed character with the last unprocessed character
               // so that we don't pick it until we process all characters in
               // this group.
               if (lastCharIdx != nextCharIdx)
               {
                  char temp = charGroups[nextGroupIdx][lastCharIdx];
                  charGroups[nextGroupIdx][lastCharIdx] = charGroups[nextGroupIdx][nextCharIdx];
                  charGroups[nextGroupIdx][nextCharIdx] = temp;
               }
               // Decrement the number of unprocessed characters in
               // this group.
               charsLeftInGroup[nextGroupIdx]--;
            }

            // If we processed the last group, start all over.
            if (lastLeftGroupsOrderIdx == 0)
               lastLeftGroupsOrderIdx = leftGroupsOrder.Length - 1;
            // There are more unprocessed groups left.
            else
            {
               // Swap processed group with the last unprocessed group
               // so that we don't pick it until we process all groups.
               if (lastLeftGroupsOrderIdx != nextLeftGroupsOrderIdx)
               {
                  int temp = leftGroupsOrder[lastLeftGroupsOrderIdx];
                  leftGroupsOrder[lastLeftGroupsOrderIdx] = leftGroupsOrder[nextLeftGroupsOrderIdx];
                  leftGroupsOrder[nextLeftGroupsOrderIdx] = temp;
               }
               // Decrement the number of unprocessed groups.
               lastLeftGroupsOrderIdx--;
            }
         }

         // Convert password characters into a string and return the result.
         return new string(password);
      }
   }
}

This is used like this: string myRandomString = RndStr.Generate();.

Standardization

Microsoft has submitted C# to the ECMA for formal standardization. In December 2001, ECMA released ECMA-334 C# Language Specification. C# became an ISO standard in 2003 (ISO/IEC 23270). There are independent implementations being worked on, including:

More recently, Microsoft has announced plans to add support for generics (similar to C++ templates), partial types and some other new features. Those additions have been proposed for ECMA/ISO standardization, but are not currently part of the standard language definition.

Politics

Many of Microsoft’s products and initiatives generate political attention, and C# is no exception. Due to C#’s close relationship with a commercial institution, political discussions continue regarding the legitimacy of C# standardization, its Java similarities, its future as a general-purpose language, and other various debates. Some security experts express skepticism as to the efficacy of the CLR's security mechanisms, and criticise their complexity.

Unlike proprietary languages such as Visual Basic or Java, Microsoft chose to open C# up to the standardization process. However, Microsoft is still a primary force driving changes and innovation in the language. Additionally, Microsoft has made it clear that C#, as well as the other .NET languages, is an important part of its software strategy for both internal use and external consumption. Microsoft takes an active role in marketing the language as part of its overall business strategy.

See also

External links

Last updated: 09-12-2005 02:39:13