C# Faq
C# Faq
C# Faq
• 1. Introduction
o 1.1 What is C#?
o 1.2 How do I develop C# apps?
o 1.3 Where can I download the .NET SDK & Visual Studio.NET?
o 1.4 Does C# replace Java?
o 1.5 Does C# replace C++?
o 1.6 What does a simple C# program look like?
o 1.7 Is C# object-oriented?
o 1.8 Does C# have its own class library?
• 2. Basic types
o 2.1 What standard types does C# supply?
o 2.2 Is it true that all C# types derive from a common base class?
o 2.3 So this means I can pass an instance of a value type to a
methodthat takes an object as a parameter?
o 2.4 What are the fundamental differences between value types
andreference types?
o 2.5 Okay, so an int is a value type, and a class is areference type. How
can int be derived from object?
o 2.6 C# uses references instead of pointers. Are C# references the
sameas C++ references?
8850540.doc Page 1 of 19
• 4. Exceptions
o 4.1 Can I use exceptions in C#?
o 4.2 What types of object can I throw as exceptions?
o 4.3 Can I define my own exceptions?
o 4.4 Are there any standard exceptions that I can re-use?
o 4.5 Does the System.Exception class have any cool features?
o 4.6 When should I throw an exception?
o 4.7 Does C# have a 'throws' clause?
• 8. Miscellaneous
o 8.1 String comparisons using == seem to be case-sensitive? How do I
doa case-insensitive string comparison?
o 8.2 I've seen some string literals which use the @ symbol, and
somewhich don't. What's that all about?
o 8.3 Does C# support a variable number of arguments?
o 8.4 How can I process command-line arguments?
o 8.5 Does C# do array bounds checking?
8850540.doc Page 2 of 19
o 8.6 How can I make sure my C# classes will interoperate with other
.NETlanguages?
• 9. Resources
o 9.1 Recommended books
o 9.2 Internet Resources
o 9.3 Sample code and utilities
1. Introduction
The (free) .NET SDK contains the C# command-line compiler (csc.exe). Visual
Studio.NET has fully integrated support for C# development.
1.3 Where can I download the .NET SDK & Visual Studio.NET?
8850540.doc Page 3 of 19
1.5 Does C# replace C++?
The obvious answer is no. However it's difficult to see C++ as the best choice for
new .NET code. For the .NET runtime to function fully, it requires the programming
language to conform to certain rules - one of these rules is that language types
must conform to the Common Type System (CTS). Unfortunately many C++
features are not supported by the CTS - for example multiple inheritance of
classes and templates.
Microsoft's answer to this problem is to offer Managed Extensions (ME) for C++,
which allows you to write C++ that conforms to the CTS. New keywords are
provided to mark your C++ classes with CTS attributes (e.g. __gc for garbage
collection). However, it's difficult to see why ME C++ would be chosen over C# for
new projects. In terms of features they are very similar, but unlike C++, C# has
been designed from the ground-up to work seamlessly with the .NET environment.
The raison d'etre for ME C++ would therefore appear to be porting existing C++
code to the .NET environment.
So, in answer to the question, my suspicion is that C++ will remain an important
language outside of the .NET environment, and will be used (via ME) to port
existing code to .NET, but I think C# will become the language of choice for one-
time C++ developers developing new .NET applications. But only time will tell ...
Sorry, my imagination has deserted me. Yes, you guessed it, here comes 'Hello,
world' ...
class CApplication
{
public static void Main()
{
System.Console.Write( "Hello, new .NET world." );
}
}
(No, you can't put Main() as a global function - global functions don't exist in C#.)
1.7 Is C# object-oriented?
Not exactly. In common with all .NET languages (e.g. VisualBasic.NET, JScript.NET)
C# has access to the .NET class library. C# does not have its own class library.
8850540.doc Page 4 of 19
2. Basic types
C# supports a very similar range of basic types to C++, including int, long, float,
double, char, string, arrays, structs and classes. However, don't assume too much.
The names may be familiar, but some of the details are different. For example, a
long is 64 bits in C#, whereas in C++ the size of a long depends on the platform
(typically 32 bits on a 32-bit platform, 64 bits on a 64-bit platform). Also classes
and structs are almost the same in C++ - this is not true for C#.
2.2 Is it true that all C# types derive from a common base class?
Yes and no. All types can be treated as if they derive from object
(System.Object), but in order to treat an instance of a value type (e.g. int, float)
as object-derived, the instance must be converted to a reference type using a
process called 'boxing'. In theory a developer can forget about this and let the
run-time worry about when the conversion is necessary, but in reality this implicit
conversion can have side-effects that may trip up the unwary.
class CApplication
{
public static void Main()
{
int x = 25;
string s = "fred";
DisplayMe( x );
DisplayMe( s );
}
You are 25
You are fred
8850540.doc Page 5 of 19
2.4 What are the fundamental differences between value types andreference
types?
C# divides types into two categories - value types and reference types. Most of
the basic intrinsic types (e.g. int, char) are value types. Structs are also value
types. Reference types include classes, interfaces, arrays and strings. The basic
idea is straightforward - an instance of a value type represents the actual data
(stored on the stack), whereas an instance of a reference type represents a
pointer or reference to the data (stored on the heap).
The most confusing aspect of this for C++ developers is that C# has
predetermined which types will be represented as values, and which will be
represented as references. A C++ developer expects to take responsibility for this
decision.
2.5 Okay, so an int is a value type, and a class is areference type. How can
int be derived from object?
It isn't, really. When an int is being used as an int, it is a value (on the stack).
However, when it is being used as an object, it is a reference to an integer value
on the heap. In other words, when you treat an int as an object, the runtime
automatically converts the int value to an object reference. This process is called
boxing. The conversion involves copying the contents of the int from the stack to
the heap, and creating an object instance which refers to it. Unboxing is the
reverse process - the object is converted back to a stack-based value.
8850540.doc Page 6 of 19
Not quite. The basic idea is the same, but one significant difference is that C#
references can be null . So you cannot rely on a C# reference pointing to a valid
object. If you try to use a null reference, a NullReferenceException is thrown.
string s = null;
displayStringLength( s );
3.1 Structs are largely redundant in C++. Why does C# have them?
In C++, a struct and a class are pretty much the same thing. The only difference
is the default visibility level (public for structs, private for classes). However, In C#
structs and classes are very different. In C#, structs are value types (stored on
the stack), whereas classes are reference types (stored on the heap). Also structs
cannot inherit from structs or classes, though they can implement interfaces.
Structs cannot have destructors.
8850540.doc Page 7 of 19
3.3 Is a C# interface the same as a C++ abstract class?
No, not quite. An abstract class in C++ cannot be instantiated, but it can (and
often does) contain implementation code and/or data members. A C# interface
cannot contain any implementation code or data members - it is simply a group of
method names & signatures. A C# interface is more like a COM interface than a
C++ abstract class.
The other major difference is that a C# class can inherit from only one class
(abstract or not), but can implement multiple interfaces.
Very similar.
No! They look the same but they're very different. First of all, a C# destructor isn't
guaranteed to be called at any particular time. In fact it's not guaranteed to be
called at all. Truth be told, a C# destructor is really just a Finalize method in
disguise. In particular, it is a Finalize method with a call to the base class Finalize
method inserted. So this:
class CTest
{
~CTest()
{
System.Console.WriteLine( "Bye bye" );
}
}
is really this:
class CTest
{
protected override void Finalize()
{
System.Console.WriteLine( "Bye bye" );
base.Finalize();
}
}
With the arrival of Beta 2, explicitly overriding Finalize() like this is not allowed -
the destructor syntax must be used.
3.6 If C# destructors are so different to C++ destructors, why did MSuse the
same syntax?
8850540.doc Page 8 of 19
Because they're evil, and they want to mess with your mind.
A constructor for a class, rather than instances of a class. The static constructor is
called when the class is loaded.
No. Like C++, methods are non-virtual by default, but can be marked as virtual.
Use the abstract modifier on the method. The class must also be marked as
abstract (naturally). Note that abstract methods cannot have an implementation
(unlike pure virtual C++ methods).
4. Exceptions
Yes, as long as you follow the rule that exceptions derive from System.Exception.
More specifically, MS recommend that user-defined exceptions inherit from
System.ApplicationException (which is derived from System.Exception).
8850540.doc Page 9 of 19
Yes, and some of them loosely correspond to standard COM HRESULTs. The table
below shows a mapping from HRESULTs to .NET (and therefore C#) exceptions:
E_POINTER ArgumentNullException
E_NOTIMPL NotImplementedException
E_OUTOFMEMORY OutOfMemoryException
Yes - the feature which stands out is the StackTrace property. This provides a call
stack which records where the exception was thrown from. For example, the
following code:
using System;
class CApp
{
public static void Main()
{
try
{
f();
}
catch( Exception e )
{
Console.WriteLine( "System.Exception stack trace =
\n{0}", e.StackTrace );
}
}
8850540.doc Page 10 of 19
throw new Exception( "f went pear-shaped" );
}
}
Note, however, that this stack trace was produced from a debug build. A release
build may optimise away some of the method calls which could mean that the call
stack isn't quite what you expect.
This is the subject of some debate, and is partly a matter of taste. However, it is
accepted by many that exceptions should be thrown only when an 'unexpected'
error occurs. How do you decide if an error is expected or unexpected? This is a
judgement call, but a straightforward example of an expected error is failing to
read from a file because the seek pointer is at the end of the file, whereas an
example of an unexpected error is failing to allocate memory from the heap.
No, unlike Java, C# does not require (or even allow) the developer to specify the
exceptions that a method can throw.
using System;
class CApp
{
public static void Main()
{
string s = "fred";
long i = 10;
8850540.doc Page 11 of 19
Console.WriteLine( "{0} is {1}an integer", s, (IsInteger(s) ? "" :
"not ") );
Console.WriteLine( "{0} is {1}an integer", i, (IsInteger(i) ? "" :
"not ") );
}
Yes, use the GetType method of the object class (which all types inherit from). For
example:
using System;
class CTest
{
class CApp
{
public static void Main()
{
long i = 10;
CTest ctest = new CTest();
DisplayTypeInfo( ctest );
DisplayTypeInfo( i );
}
8850540.doc Page 12 of 19
Type name = CTest, full type name = CTest
Type name = Int64, full type name = System.Int64
using System;
delegate void Stereotype();
class CAmerican
{
public void BePatriotic()
{
Console.WriteLine( "... <gulp> ... God bless America.");
}
}
class CBrit
{
public void BeXenophobic()
{
Console.WriteLine( "Bloody foreigners ... " );
}
}
class CApplication
{
public static void RevealYourStereotype( Stereotype[] stereotypes )
{
foreach( Stereotype s in stereotypes )
s();
}
8850540.doc Page 13 of 19
stereotypes[0] = new Stereotype( chuck.BePatriotic );
stereotypes[1] = new Stereotype( edward.BeXenophobic );
// Reveal yourselves!
RevealYourStereotype(stereotypes );
}
}
using System;
interface IPerson
{
string GetName();
}
// IPerson
public string GetName()
{
return m_name;
}
8850540.doc Page 14 of 19
private string m_name;
}
// IPerson2
public string GetName() { return m_name; }
public int GetAge() { return m_age; }
private string m_name; private int m_age;
}
DisplayAge( bob );
DisplayAge( sheila );
}
8850540.doc Page 15 of 19
7.1 I 'new'-ed an object, but how do I delete it?
You can't. You are not allowed to call the destructor explicitly, and no delete
operator is provided. Don't worry, the garbage collector will destroy your object ....
eventually .... probably .... :-)
Unlike C++, you cannot create instances of classes on the stack. Class instances
always live on the heap and are managed by the garbage collector.
7.4 Most of the C# basic types have the same names as C++ basic types?Are
they the same?
8. Miscellaneous
Use the String.Compare function. Its third parameter is a boolean which specifies
whether case should be ignored or not.
8.2 I've seen some string literals which use the @ symbol, and somewhich
don't. What's that all about?
8850540.doc Page 16 of 19
The @ symbol before a string literal means that escape sequences are ignored.
This is particularly useful for file names, e.g.
versus:
Yes, using the params keyword. The arguments are specified as a list of
arguments of a specific type, e.g. int. For ultimate flexibility, the type can be
object. The standard example of a method which uses this approach is
System.Console.WriteLine().
Like this:
using System;
class CApp
{
public static void Main( string[] args )
{
Console.WriteLine( "You passed the following arguments:" );
foreach( string arg in args )
Console.WriteLine( arg );
}
}
8.6 How can I make sure my C# classes will interoperate with other
.NETlanguages?
Make sure your C# code conforms to the Common Language Subset (CLS). To help
with this, add the [assembly:CLSCompliant(true)] global attribute to your C#
source files. The compiler will emit an error if you use a C# feature which is not
CLS-compliant.
8850540.doc Page 17 of 19
9. Resources
8850540.doc Page 18 of 19
8850540.doc Page 19 of 19