This blog is moved to
http://amalhashim.wordpress.com

Saturday, June 6, 2009

C# Namespace And Assemblies - Part 1

Visual studio compilers produces assemblies as output.
Assemblies can be executables as well as class libraries.

Example of a class library

public class Calculator
{
int value1, int value2;
public Calculator(int value1, int value2)
{
this.value1 = value1;
this.value2 = value2;
}

public int Add()
{
return this.value1 + this.value2;
}

public int Add(int value1, int value2)
{
return value1 + value2;
}
}

When we compile this class using a C# compiler to produce a class library (Calculator.dll).

If we want to use Calculator object in say MyApplication

class MyApplication
{
static void Main()
{
Calculator calc = new Calculator(10, 20);
Console.WriteLine(calc.Add());
Console.WriteLine(calc.Add(20, 30));
}
}

The above code doesn't declare class Calculator, instead we will be using the classlibrary which contains the declaration of Calculator. But for MyApplication to compile properly, the compiler must be aware of the code in the assembly Calculator. For achieving this we need to give the compiler a reference to the assembly, by giving its name and location.

In Visual studio we can add references to a project by right clicking the project from solution explorer and adding reference to Calculator.dll

Once the reference is added MyApplication will compile properly.

The MsCorLib library

mscorlib is the assembly which contains the Console class. It resides in mscorlib.dll assembly. It also holds C# types and the basic types for most. This assembly is always required because of this Visual studio won't be displaying it under references folder.

Now if we have another Calculator class in say assembly Calculator1.dll.
If we use Calculator in MyApplication then a name clash can happen.

Namespaces

Namespace feature will help us to avoid the above problem. Namespaces group a set of types together and give them a name called the namespace name.

namespace SampleNamespace
{
TypeDeclarations
}

Namespace can contains period

namespace ABC.Calculator
{
public class Calculator
{
}
}

namespace XYZ.Calculator
{
public class Calculator
{
}
}

Now we can use both Calculator class and avoid the conflict.

In MyApplication we can qualify Calculator class as

ABC.MyCalculator.Calculator calc = new ABC.MyCalculator.Calculator();
XYZ.OurCalculator.Calculator newCalc = new XYZ.OurCalculator.Calculator();

Namespace can be any valid identifier. Period can be used to organize types into hierarchies.

1. Start namespace names with the company name.
2. Follow the company name with technology name.
3. Do not name a namespace with the same name as a class or type
4. Every type in a namespace must be different from all the others
5. The types in a namespace are called members of the namespace

BCL offers thousands of classes and types for building applications. Namespaces help to organize the related functionality in the same namespace.

Namespace is not closed in a single source file.

Namespace can be a member of another namespace. The member is called a nested namespace.
Two types of nesting

Textual nesting

namespace Nested
{
namespace Nested1
{
}
}

Separate declaration

namespace Nested
{
}

namespace Nested.Nested1
{
}

Using Directives


Since fully qualified names can be quite long, compiler gives flexibility to shorten it using either using namespace directive or using alias directive. We must be use the using directive on top of the source file before any type declarations. They will be applied for all the namespaces in the current source file.

Example

using System;

so in MyApplication we can use as

Console.WriteLine("") instead of System.Console.WriteLine

Using Sys = System;

Sys.Console.WriteLine("")

Thursday, June 4, 2009

Validating URL using C#

Regex RgxUrl = new Regex("(([a-zA-Z][0-9a-zA-Z+\\-\\.]*:)?/{0,2}[0-9a-zA-Z;/?:@&=+$\\.\\-_!~*'()%]+)?(#[0-9a-zA-Z;/?:@&=+$\\.\\-_!~*'()%]+)?");
if (RgxUrl.IsMatch(txtUrl.Text))
{
MessageBox.Show("URL is valid.");
}
else
{
MessageBox.Show("URL is invalid!");
}

The above code will validate URL's without http also. Alternatively you can use this

System.Globalization.CompareInfo cmpUrl = System.Globalization.CultureInfo.InvariantCulture.CompareInfo;
if(cmpUrl.IsPrefix(txtUrl.Text, "http://") == false)
{
txtUrl.Text = "http://" + txtUrl.Text;
}
Regex RgxUrl = new Regex("(([a-zA-Z][0-9a-zA-Z+\\-\\.]*:)?/{0,2}[0-9a-zA-Z;/?:@&=+$\\.\\-_!~*'()%]+)?(#[0-9a-zA-Z;/?:@&=+$\\.\\-_!~*'()%]+)?");
if (RgxUrl.IsMatch(txtUrl.Text))
{
MessageBox.Show("URL is valid.");
}
else
{
MessageBox.Show("URL is invalid!");
}

Wednesday, June 3, 2009

C# Preprocessor Directives

Preprocessor directives guides the compiler how to treat the source code. In some scenarios we need to ignore some portions of the code, in such scenarios preprocessor directive can help. C# preprocessor directives are handled by the compiler.

Rules

1. Preprocessor directives must be on separate line
2. Must not terminate with semicolon compared to normal C# statements
3. Starts with # character
4. End of line comments are not allowed
5. Delimited comments are not allowed

Example

#define Version1

Preprocessor Directives


#define identifier - Defines a compilation symbol
#undef identifier - Undefines a compilation sysmbol
#if expression - If the expression is true, compiles the following section
#elif expression - If the expression is true, compiles the following section
#else - If the previous #if or #elif expression is false, compiles the following section
#endif - Marks the end of an #if construct
#region name - Marks the beginning of a region of code
#endregion name - Marks the end of a region
#warning message - Displays a compile time warning message
#error message - Displays a compile time error message
#line indicator - Changes the line number displayed in compiler messages
#pragma text - Specifies information about the program context


#define and #undef

It can be any identifier except true or false. It will be represented as a string.

#define declares a symbol while #undef undefines a symbol.

#define Version1
#define Version2
....

#undef Version1

One thing we must remeber is, both #define and #undef must be used before any C# code. After code the #define and #undef directives can no longer be used.

using System;

#define Version1

namespace MySampelNamespace
{

#define Version2 /// Erro

The symbol scope is limited to a single source file.

Conditional Compilation

Helps use to mark a section of source code to be either compiled or skipped.

Condition is an expression which can be evaluated to either true or false.
Expression can have the following operators
!, ==, !=, &&, ||

#if !Version1
///Code
#endif

#if true
///Code
#endif

#if !Version1
///Code
#else
///Code
#endif

#if !Version1
///Code
#elif !Version2
///Code
#else
///Code
#endif

Diagnostic Directives

#warning Message

#error Message

The diagnostic messages will be listed along with the compiler generated warnings and error messages.

#if !Version1
#warning Version1 is not defined compiling version specific code
#end if

Line Number Directives

This directive can be used to do the following things
1. Change the line numbers reported by the compiler's warning and error messages
2. Change the filename of the source file being compiled
3. Hide a sequence of lines from the interactive debugger

#line integer
#line "filename"
#line default // Restores the real line number and filename

#line hidden //Hides the following code from stepping debugger
#line //Stops hiding from debugger

#line 250
sum = total + expense; /// From here the line number will be 250

#line 200 "changefile.cs" /// From here the line number and file will be changed

Region Directives

#region name
///Code for region 1
#endregion

This directive is used by visual studio for hiding and displaying regions

The Pragma warning Directive

Allows to turn off warning messages and to turn them back on.

#pragma warning diable 100, 200 /// Warning messages on line 100 and 200 will be diabled

#pragma warning restore 100 /// restore the warning @ line 100

#pragma warning disable /// disable all warning

#pragma warning restore /// enable all warning

Sunday, May 31, 2009

Monday, May 25, 2009

Single Instance application using C#

Single instance application.

We can use two ways to solve this problem.
1. Using Mutex
2. Using Process list and checking for the any other running instance

Option1

static void Main() {
bool running;
System.Threading.Mutex mutex = new System.Threading.Mutex(true, "applicationName", out running);
if(!running) {
MessageBox.Show("Another instance is already running.");
return;
}
Application.Run(new Form1());
GC.KeepAlive(mutex);
}

Option2

static void Main() {
bool flag;
Process curr = Process.GetCurrentProcess();
Process[] procs = Process.GetProcessesByName(curr.ProcessName);
foreach (Process p in procs) {
if ((p.Id != curr.Id) && (p.MainModule.FileName == curr.MainModule.FileName)) {
flag = true;
break;
}
}

if(flag) {
MessageBox.Show("Application already running");
return;
}

Application.Run(new Form1());
}

Friday, May 22, 2009

Linq and C# - Part 2

Linq queries with Restriction Operators

1=>


Prints each element of an input integer array whose value is less than 5.

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0);

var lowNums = from n in numbers
where n < 5 select n;

foreach(var x in lowNums) {
Console.WriteLine(x);
}

2=>

class Product {
string ProducName { get; set; }
int Units { get; set; }
int Price { get; set; }
}

Listing of all products that are out of stock.

// Fill products

var soldOutProducts = from p in products
where p.Units == 0
select p;

foreach(var pr in soldOutProducts) {
Console.WriteLine(pr.Name);
}

3=>

Lists all expensive items in stock.

var expensiveInStockProducts =
from p in products
where p.Units > 0 && p.Price > 3

foreach (var product in expensiveInStockProducts) {
Console.WriteLine(product.Name);
}

4=>

This sample uses an indexed Where clause to print the name of each number, from 0-9, where the length of the number's name is shorter than its value. In this case, the code is passing a lamda expression which is converted to the appropriate delegate type. The body of the lamda expression tests whether the length of the string is less than its index in the array.

string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };

var shortDigits = digits.Where((digit, index) => digit.Length < index);

Console.WriteLine("Short digits:");
foreach (var d in shortDigits) {
Console.WriteLine("The word {0} is shorter than its value.", d);
}

Get Path where the Executable is running from in C#

Option#1
string path1 = System.Windows.Forms.Application.ExecutablePath;

Option#2
String path2 = System.Reflection.Assembly.GetExecutingAssembly().Location;