Monday, October 13, 2008


Q: What is C#?
A: C# is a programming language designed by Microsoft. It is loosely based on C/C++, and bears a striking similarity to Java in many ways. Microsoft describe C# as follows:

"C# is a simple, modern, object oriented, and type-safe programming language derived from C and C++. C# (pronounced 'C sharp') is firmly planted in the C and C++ family tree of languages, and will immediately be familiar to C and C++ programmers. C# aims to combine the high productivity of Visual Basic and the raw power of C++."

Q: Does C# replace Java?
A: C# is a very Java-like language - the core of both languages have similar advantages and limitations when compared to C++. For example, both languages have garbage collection, but neither language has templates. Microsoft have ceased production of Visual J++, so it's hard not to view C# as Microsoft's alternative to Java.

Q: Does C# replace C++?
A: 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 ...

Q: What does a simple C# program look like?
A: This is the Hello World program:

class CApplication
public static void Main()
System.Console.Write( "Hello, new .NET world." );

Q: Is C# object-oriented?
A: Yes, C# is an OO language in the tradition of Java and C++.

Q: Does C# have its own class library?
A: 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.

Q: How do I develop C# apps?
A: The (free) .NET SDK contains the C# command-line compiler (csc.exe). Visual Studio.NET has fully integrated support for C# development. You need to download the .NET SDK and then whatever compiler or IDE you'd like to use.
Also, there is a free C# IDE, here:

For more tools and utilities, check our Links section.

Q: Are there any free C# IDEs that I could use?
A: Yes, there are!
Check this one for example:

Also, feel free to check our Links section to browse for more tools and utilities.

Q: Can I program 3D games with C#?
A: Yes, you can!
Check out our Graphics/GDI+ tutorials. You could eventually find what you need, there.

Q: What is Common Language Runtime (CLR)?
A: As part of Microsoft's .NET Framework, the Common Language Runtime (CLR) is programming that manages the execution of programs written in any of several supported languages, allowing them to share common object-oriented classes written in any of the languages. The Common Language Runtime is somewhat comparable to the Java virtual machine that Sun Microsystems furnishes for running programs compiled from the Java language. Microsoft refers to its Common Language Runtime as a "managed execution environment." A program compiled for the CLR does not need a language-specific execution environment and can easily be moved to and run on any system with Windows 2000 or Windows XP.
Programmers writing in any of Visual Basic, Visual C++, or C# compile their programs into an intermediate form of code called Common Intermediate Language (CIL) in a portable execution (PE) file that can then be managed and executed by the Common Language Runtime. The programmer and the environment specify descriptive information about the program when it is compiled and the information is stored with the compiled program as metadata. Metadata, stored in the compiled program, tells the CLR what language was used, its version, and what class libraries will be needed by the program. The Common Language Runtime allows an instance of a class written in one language to call a method of a class written in another language. It also provides garbage collecting (returning unneeded memory to the computer), exception handling, and debugging services.

Q: What is boxing and unboxing?
A: Boxing and unboxing is a essential concept in C#’s type system. With Boxing and unboxing one can link between value-types and reference-types by allowing any value of a value-type to be converted to and from type object. Boxing and unboxing enables a unified view of the type system wherein a value of any type can ultimately be treated as an object. Converting a value type to reference type is called Boxing. Unboxing is an explicit operation.

For more information, please, read this article- Boxing And Unboxing C#

Q: Are there pointers in C#?
A: There are no pointers in the C# language, although you can use pointers in your C# applications, as long as you put them into the "unsafe code" space:


// unsafe context: can use pointers here


Q: What are delegates?
A: A delegate in C# is similar to a function pointer in C or C++. Using a delegate allows the programmer to encapsulate a reference to a method inside a delegate object. The delegate object can then be passed to code which can call the referenced method, without having to know at compile time which method will be invoked. Unlike function pointers in C or C++, delegates are object-oriented, type-safe, and secure.

For more information about delegates, please, check out our Delegates tutorials.
Also, feel free to check out our Delegates FAQ.

Q: Are there Certification exams for C#?
A: Yes, in fact, there already are 3 exams, 70-315, 70-316, and 70-320. Check these links for more information.

Q: Can I use MySQL with C#?
A: Yes, you can use MySQL with C#.
You can connect to the database by using ODBC driver and the System.Data.Odbc namespace.

Q: Can I use DirectX in C#?
A: Yes, you can!

Check out this article- DirectX in C#.

Also, feel free to check out our Graphics/GDI+/Images/Fonts tutorials.

Q: Is it possible to have a static indexer in C#?
A: No, they are not allowed in C#.

Q: Can I use inline assembly or IL in C# code?
A: No.

Q: Does C# have macros or a preprocessor?
A: C# doesn't have macros as such, nor does it strictly speaking have a pre-processor, but it does have conditional compilation symbols which can be used to affect compilation. These can be defined within code or with parameters to the compiler. The "pre-processing" directives in C# (named solely for consistency with C/C++, despite there being no separate pre-processing step) are (text taken from the ECMA specification):
#define and #undef
Used to define and undefine conditional compilation symbols
#if, #elif, #else and #endif
Used to conditionally skip sections of source code
Used to control line numbers emitted for errors and warnings.
#error and #warning
Used to issue errors and warnings.
#region and #endregion
Used to explicitly mark sections of source code.

See section 9.5 of the ECMA specification for more information on the above. Conditional compilation can also be achieved using the Conditional attribute on a method, so that calls to the method will only be compiled when the appropriate symbol is defined. See section 24.4.2 of the ECMA specifcation for more information on this.

Q: Does C# have templates like C++?
A: Although C# doesn't have templates, and isn't likely to get them, it is getting a feature called generics which will be available in Whidbey, the next version of .NET, which should be available in the first half of 2005. (A beta version is currently available.) Generics will be a feature in the CLR itself, and most languages targetting the CLR will change to support it. Generics provide a lot of the functionality of C++ templates (mostly in terms of type safety) but in a more restricted (and therefore potentially less confusing) way.

Q: Why can't I use static and const together?
A: All constants declarations are implicitly static, and the C# specification states that the (redundant) inclusion of the static modifier is prohibited. I believe this is to avoid the confusion which could occur if a reader were to see two constants, one declared static and one not - they could easily assume that the difference in specification implied a difference in semantics. (Having said that, there is no prohibition on redundantly specifying an access modifier which is also the default one, where there is a choice. For instance, a (concrete) method can be explicitly marked as private despite that being the default. The rule appears to be that where there is no choice (e.g. a method declaration in an interface) the redundant modifier is prohibited. Where there is a choice, it's allowed.

C# Frequently Asked Questions

The C# team posts answers to common questions

* How do I send out simple debug messages to help with my debugging?

Visual Studio offers tons of useful debugging features and allows you to step through your code line-by-line. However, there are times when you don’t want to step through your application, but want to make it output simple text strings with variable values, etc.

Enter the System.Diagnostics.Debug class and its Write* methods. By using the Debug class, you can output messages similarly to the way the Win32 API function OutputDebugString. However, the beauty of the Debug class is that when you build your application using the default Release configuration in Visual Studio, no code lines are generated for your Debug.Write* class. This means there’s no performance penalty for using the Debug class in release code.

To use the Debug class, simply add the “using System.Diagnostics;” statement to your C# code file, and call Debug.Write:

Debug.Write("Hello, Debugger!");

In addition to Write, you have the possibility to call WriteIf, WriteLine and WriteLineIf. For example:

bool @this = true;

bool that = false;

Debug.WriteLineIf(@this || that, "A conditional Hello!");

When you are debugging your application under the Visual Studio debugger, all the messages that are sent out by your Write method calls end up in the Output window (View / Output menu command or Ctrl+W,O on the keyboard). However, if you are running your application outside the debugger (say, by starting it from Windows Explorer), you can still view the messages using tools like DebugView from Sysinternals.

Remember, if you build your application using the default Release configuration, even DebugView won’t show your messages because the Debug.Write* calls are eliminated altogether. You can also control code generation by defining the DEBUG conditional directive.

Tip: The .NET debugging/tracing architecture also allows you to redirect debugging messages to different destinations, such as text files. See the help topic “Trace Listeners” for more information.

[author: Jani Järvinen, C# MVP]

Posted Monday, October 09, 2006 11:19 AM by CSharpFAQ | 1 Comments

Filed under: Debugger/Debugging

* How do I calculate a MD5 hash from a string?

It is a common practice to store passwords in databases using a hash. MD5 (defined in RFC 1321) is a common hash algorithm, and using it from C# is easy.

Here’s an implementation of a method that converts a string to an MD5 hash, which is a 32-character string of hexadecimal numbers.

public string CalculateMD5Hash(string input)


// step 1, calculate MD5 hash from input

MD5 md5 = System.Security.Cryptography.MD5.Create();

byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);

byte[] hash = md5.ComputeHash(inputBytes);

// step 2, convert byte array to hex string

StringBuilder sb = new StringBuilder();

for (int i = 0; i <>




return sb.ToString();


An example call:

string hash = CalculateMD5Hash("abcdefghijklmnopqrstuvwxyz");

…returns a string like this:


To make the hex string use lower-case letters instead of upper-case, replace the single line inside the for loop with this line:


The difference is the ToString method parameter.

[author: Jani Järvinen, C# MVP]

Posted Monday, October 09, 2006 11:15 AM by CSharpFAQ | 3 Comments

Filed under: .NET Framework

* How do I play default Windows sounds?

Sometimes, you might want to make your application a bit more audible. If you are using .NET 2.0, you can utilize the new System.Media namespace and its SystemSound and SystemSounds classes.

The SystemSounds class contains five static properties that you can use to retrieve instances of the SystemSound class. This class in turn contains the Play() method, which you can use to play the wave file associated with the sound in Windows Control Panel. Note that the user can also disable all sounds altogether, which would mean that no sound can be heard through the computer speakers.

To play for example the classical beep sound, you could use the following code:


Similarly, you could play the “Question” sound with this code:


The System.Media namespace is defined in System.dll, so there are no new DLLs you would need to add to your project’s references to use the above code.

[author: Jani Järvinen, C# MVP]

Posted Monday, March 27, 2006 7:03 PM by CSharpFAQ | 1 Comments

Filed under: .NET Framework

* How can I easily log a message to a file for debugging purposes?

Often, you need a way to monitor your applications once they are running on the server or even at the customer site -- away from your Visual Studio debugger. In those situations, it is often helpful to have a simple routine that you can use to log messages to a text file for later analysis.

Here’s a simple routine that has helped me a lot for example when writing server applications without an user interface:

using System.IO;

public string GetTempPath()


string path = System.Environment.GetEnvironmentVariable("TEMP");

if (!path.EndsWith("\\")) path += "\\";

return path;


public void LogMessageToFile(string msg)


System.IO.StreamWriter sw = System.IO.File.AppendText(

GetTempPath() + "My Log File.txt");



string logLine = System.String.Format(

"{0:G}: {1}.", System.DateTime.Now, msg);








With this simple method, all you need to do is to pass in a string like this:

LogMessageToFile("Hello, World");

The current date and time are automatically inserted to the log file along with your message.

[author: Jani Järvinen, C# MVP]

Posted Monday, March 27, 2006 6:59 PM by CSharpFAQ | 6 Comments

Filed under: Debugger/Debugging

* How can I speed up hashtable lookups with struct object as keys?

When you have struct objects as the key in a hashtable, the lookup operation of the hashtable performs miserably. This can be attributes to the GetHashCode() function which is used internally to do the lookup.

If a struct contains only simple value types (int, short, etc.), the algorithm which computes the GetHashCode creates hashes which fall into mostly the same bucket.

Example, lets say, the hashtable creates 10 buckets. Then, most probably, all the keys are being put into the same bucket. Hence when a lookup is performed, the .NET runtime has to traverse through this entire bucket to get the value.

BUCKET1 - Value1, Value2, Value3,...,valuen

BUCKET2 - (empty)

BUCKET3 - (empty)

BUCKET4 - (empty)

BUCKET5 - (empty)

BUCKET6 - (empty)

BUCKET7 - (empty)

BUCKET8 - (empty)

BUCKET9 - (empty)

BUCKET10- (empty)

Hence, instead of the lookup operation being O(1), it becomes O(n) on an average case.

To overcome this drawback, consider overriding the GetHashCode() function and making the life easier for the .NET Runtime.

An example would be to create a string by merging all your value types in the struct and joining them by using a special character as a demarcator.

Since your struct is a lookup criteria, it is sure that all the struct values will be different, and hence the string generated is guaranteed unique.

Now the string generated has a method(GetHashCode()), since it is derived from System.Object (like all other objects). Just return the output of this API. A code example will help to understand better.



int a;

short b;

public struct(int _a, short _b)


a = _a;

b = _b;


public override int GetHashCode()


string hash = a.ToString() + ":" b.ToString();

return hash.GetHashCode();



Since you are generating hashcode explicitly which is guaranteed to be unique, it will boost the performance of your lookup.


[author: Vipul Patel, C# MVP]

Posted Monday, March 20, 2006 6:54 PM by CSharpFAQ | 18 Comments

* Where can I find design and coding guidelines for .NET?

tipu_77 asked "What are microsoft suggested naming conventions in C#?"

The .NET Framework Team collects their recommendations at their

GotDotNet community site.

which points to a fairly comprehensive MSDN page

Design Guidelines for Class Library Developers.

which includes the section Naming Guidelines

[Author: SantoshZ]

Posted Monday, February 21, 2005 1:30 PM by CSharpFAQ | 4 Comments

Filed under: C# Language and Compiler, .NET Framework

* What does the /target: command line option do in the C# compiler?

All the /target: options except module create .NET assemblies. Depending on the option, the compiler adds metadata for the operating system to use when loading the portable executable (PE) file and for the runtime to use in executing the contained assembly or module.

module creates a module. The metadata in the PE does not include a manifest. Module/s + manifest make an assembly - the smallest unit of deployment. Without the metadata in the manifest, there is little the runtime can do with a module.

library creates an assembly without an entry point, by setting the EntryPointToken of the PE's CLR header to 0. If you look at the IL, it does not contain the .entrypoint clause. The runtime cannot start an application if the assembly does not have an entry point.

exe creates an assembly with an entry point, but sets the Subsystem field of the PE header to 3 (Image runs in the Windows character subsystem - see the _IMAGE_OPTIONAL_HEADER structure in winnt.h). If you ILDASM the PE, you will see this as .subsystem 0x0003. The OS launches this as a console app.

winexe sets the Subsystem field to 2. (Image runs in the Windows GUI subsystem). The OS launches this as a GUI app.

[Author: SantoshZ]
See also:
Chapter 3 of Inside Microsoft .NET IL assembler (Serge Lidin, Microsoft Press)
Metadata and the PE File Structure at MSDN
An In-Depth Look into the Win32 Portable Executable File Format - Part 1 and Part 2 (Matt Pietrek, MSDN Magazine)

Posted Saturday, December 04, 2004 11:33 PM by CSharpFAQ | 3 Comments

Filed under: C# Language and Compiler

* What is the difference between const and static readonly?

The difference is that the value of a static readonly field is set at run time, and can thus be modified by the containing class, whereas the value of a const field is set to a compile time constant.

In the static readonly case, the containing class is allowed to modify it only

o in the variable declaration (through a variable initializer)
o in the static constructor (instance constructors, if it's not static)

static readonly is typically used if the type of the field is not allowed in a const declaration, or when the value is not known at compile time.

Instance readonly fields are also allowed.

Remember that for reference types, in both cases (static and instance) the readonly modifier only prevents you from assigning a new reference to the field. It specifically does not make immutable the object pointed to by the reference.

class Program


public static readonly Test test = new Test();

static void Main(string[] args)


test.Name = "Program";

test = new Test(); // Error: A static readonly field cannot be assigned to (except in a static constructor or a variable initializer)



class Test


public string Name;


On the other hand, if Test were a value type, then assignment to test.Name would be an error.

Posted Friday, December 03, 2004 5:13 PM by CSharpFAQ | 3 Comments

Filed under: C# Language and Compiler

* How do I create a constant that is an array?

Strictly speaking you can't, since const can only be applied to a field or local whose value is known at compile time.

In both the lines below, the right-hand is not a constant expression (not in C#).

const int [] constIntArray = newint [] {2, 3, 4};

// error CS0133: The expression being assigned to 'constIntArray' must be constant

const int [] constIntArrayAnother = {2, 3, 4};

// error CS0623: Array initializers can only be used in a variable or field

// initializer. Try using a new expression instead.

However, there are some workarounds, depending on what it is you want to achieve.

If want a proper .NET array (System.Array) that cannot be reassigned, then static readonly will do for you.

static readonly int [] constIntArray = new int[] {1, 2, 3};

The constIntArray field will be initialized before it its first use.

If, on the other hand, you really need a const set of values (say as an argument to an attribute constructor), then - if you can limit yourself to integral types - an enum would serve you well.

For example:


public enum Role


Administrator = 1,

BackupOperator = 2,

// etc.


public class RoleAttribute : Attribute


public RoleAttribute()


CreateRole = DefaultRole;


public RoleAttribute(Role role)


CreateRole = role;


public Role CreateRole


get { return this.createRole; }

set { this.createRole = value; }


private Role createRole = 0;

public const Role DefaultRole = Role.Administrator

| Role.BackupOperator;



public class DatabaseAccount




RoleAttribute, instead of taking an array, would only take a single argument of flags (appropriately or-ed). If the underlying type of the Role enum is long or ulong, that gives you 64 different Roles.

[Author: SantoshZ]

Posted Friday, December 03, 2004 9:33 AM by CSharpFAQ | 5 Comments

Filed under: C# Language and Compiler, General, Tips

* How do I get and set Environment variables?

Use the System.Environment class.
Specifically the GetEnvironmentVariable and SetEnvironmentVariable methods.

Admitedly, this is not a question specific to C#, but it is one I have seen enough C# programmers ask, and the ability to set environment variables is new to the Whidbey release, as is the EnvironmentVariableTarget enumeration which lets you separately specify process, machine, and user.

Brad Abrams blogged on this way back at the start of this year, and followed up with a solution for pre-Whidbey users.

[Author: SantoshZ]

Posted Thursday, December 02, 2004 9:01 AM by CSharpFAQ | 6 Comments

Filed under: General, .NET Framework, Tips

* Is it possible to output the command-line used to build a project in Visual Studio?

Now that Whidbey has been out in Beta for more than a few months, it seems worth revisiting some frequently asked questions which have different (better?) answers now.

In Everett (v7.1) the answer used to be No.

However, in Whidbey (v8.0), the answer is Yes (and No).

For the yes part of the answer, after building, go to the Output Window, select "Show Output from: Build", and about half way down you will see a section like this:

Target "Compile" in project "ConsoleApplication1.csproj"

Task "Csc"

Csc.exe /noconfig /warn:4 /define:DEBUG;TRACE /debug+ /optimize- /out:obj\Debug\ConsoleApplication1.exe /reference:C:\WINDOWS\Microsoft.NET\Framework\v2.0.31125\System.Data.dll, C:\WINDOWS.0\Microsoft.NET\Framework\v2.0.31125\System.XML.dll, C:\WINDOWS\Microsoft.NET\Framework\v2.0.31125\System.dll /target:exe /win32icon:App.ico AssemblyInfo.cs Class1.cs

The task is invoking the IDE's in-process compiler to perform the equivalent of the above command-line.

Now for the no part of the answer. The project system does not actually execute this command line as part of the build process. As the output says, the IDE directly calls its own in-process compiler to perform the equivalent. However, in all cases, you should get the same results using the command line suggested in the output window. If you don't, you could be looking at a bug.

Note: before you cut and paste the build output to the command line, remember to add the path to CSC.EXE

[Author: SantoshZ]

Posted Tuesday, November 30, 2004 2:54 PM by CSharpFAQ | 6 Comments

Filed under: IDE, General, C# Language 2.0

* Preprocess Win32 Messages through Windows Forms

In the unmanaged world, it was quite common to intercept Win32 messages as they were plucked off the message queue. In that rare case in which you wish to do so from a managed Windows Forms application, your first step is to build a helper class which implements the IMessageFilter interface. The sole method, PreFilterMessage(), allows you to get at the underlying message ID, as well as the raw WPARAM and LPARAM data. By way of a simple example:

public class MyMessageFilter : IMessageFilter


public bool PreFilterMessage(ref Message m)


// Intercept the left mouse button down message.

if (m.Msg == 513)


MessageBox.Show("WM_LBUTTONDOWN is: " + m.Msg);

return true;


return false;



At this point you must register your helper class with the Application type:

public class mainForm : System.Windows.Forms.Form


private MyMessageFilter msgFliter = new MyMessageFilter();

public mainForm()


// Register message filter.




At this point, your custom filter will be automatically consulted before the message makes its way to the registered event hander. Removing the filter can be accomplished using the (aptly named) static Application.RemoveMessageFilter() method.

Tip from Andrew Troelsen
Posted by: Duncan Mackenzie, MSDN
This post applies to Visual C# .NET 2002/2003

Posted Wednesday, October 20, 2004 4:59 PM by CSharpFAQ | 7 Comments

Filed under: Tips

* Be Mindful of the References / 'using' / Manifest Relationship

Given that the .NET platform encourages binary reuse of types, it is commonplace to set references to external assemblies using the Visual Studio .NET Add Reference dialog box. Many programmers (especially those of the C(++) ilk) fear that adding unnecessary external references can result in a bit of 'code bloat'. Nothing could be further from the truth. When you add assembly references or make use of the 'using' keyword, csc.exe will ignore any assembly which you have not actually made use of in your code. Thus, if you were to set a reference to System.Data.dll and System.Windows.Forms.dll but only authored the following code:

using System;

using System.Data; // Ignored.

using System.Windows.Forms; // Ignored.

public class MyClass


public static void Main()


Console.WriteLine("Hi there.");



the compiler would only reference the mandatory mscorlib.dll.

As you may be aware, when you open up a .NET assembly using ildasm.exe, the MANIFEST icon may be double clicked to open a window describing the binary under investigation. At the very top, you will see a list of each external assembly the current assembly was compiled against (provided that it was actually used):

.assembly extern mscorlib

{ … }

Bottom line? Don't waist your time stripping out unused 'using' statements or assembly references from your application. The C# compiler will do so for you automatically.

Tip from Andrew Troelsen
Posted by: Duncan Mackenzie, MSDN
This post applies to Visual C# .NET 2002/2003/2005

Posted Wednesday, October 20, 2004 4:58 PM by CSharpFAQ | 8 Comments

Filed under: Tips

* Activate 'Full Screen Mode' During your Source Code Editing

Okay, I admit this is a rather lame tip which can hardly qualify as 'insightful', however this is one of my favorite features of Visual Studio .NET (as well as previous editions of the Visual Studio product line) which many folks are (surprisingly) unaware of. Under the View menu you will find a menu item named 'Full Screen'. When activated, the only window displayed will be the active document. This is especially helpful for those working on low resolution monitors, given that the size of your code window can shrink dramatically if you have too many windows docked within the IDE. To escape from full screen, just click the Full Screen button floating over your code window.

Tip from Andrew Troelsen
Posted by: Duncan Mackenzie, MSDN
This post applies to Visual C# .NET 2002/2003/2005

Posted Wednesday, October 20, 2004 4:50 PM by CSharpFAQ | 8 Comments

Filed under: Tips

* Leverage the C# Preprocessor

Like other languages in the C-family, C# supports a set of 'preprocessor' directives, most notably #define, #if and #endif (technically, csc.exe does not literally have a preprocessor as these symbols are resolved at the lexical analysis phase, but no need to split hairs…).

The #define directive allows you to set up custom symbols which control code compilation. Be very aware that unlike C(++), C#'s #define does not allow you to create macro-like code. Once a symbol is defined, the #if and #endif maybe used to test for said symbol. By way of a common example:

#define DEBUG

using System;

public class MyClass


public static void Main()



Console.WriteLine("DEBUG symbol is defined!");




When you use the #define directive, the symbol is only realized within the defining file. However if you wish to define project wide symbols, simply access your project's property page and navigate to the "Configuration Properties | Build" node and edit the "Conditional Compilation Constants" edit field. Finally, if you wish to disable a constant for a given file, you may make use of the #undef symbol.