Showing posts with label Visual Studio. Show all posts
Showing posts with label Visual Studio. Show all posts

Thursday, August 21, 2008

Generics

In framework 2 Microsoft introduced support for generic types. Generic can take on any type; it might sound familiar to you; objects can do exactly the same. Generics are to replace objects when possible, since they firstly improve the performance by eliminating the need to boxing and unboxing, secondly decrease the number of run-time errors caused by incorrect casting.

Here is an example of incorrect casting:

object MyObj=new object();

MyObj="Not an integer";

int MyNumber=(int)MyObj;//CAUSES RUN-TIME ERROR

The above mistake won't be caught by the compiler and as a result will generate a run-time error.

The class definition does not provide the exact variable types and when the class is used, the exact types are passed to the class.

The following is the definition of a class that uses generic concept:

class MyGenericClass<MyGenericTypeOne,MyGenericTypeTwo>
    {
        private MyGenericTypeOne MyFieldOne;
        private MyGenericTypeTwo MyFieldTwo;
        public MyGenericTypeOne MyPropertyOne
        {
            get
            {
                return MyFieldOne;
            }
            set
            {
                MyFieldOne = value;
            }
        }

        public MyGenericTypeTwo MyPropertyTwo
        {
            get
            {
                return MyFieldTwo;
            }
            set
            {
                MyFieldTwo = value;
            }
        }
    }

 

MyGenericTypeOne and MyGenericTypeTwo are two generic types that the above class uses.

The following code consumes the above class:

 

MyGenericClass<string,int> NewInstanceOne=new MyGenericClass<string,int>();
NewInstanceOne.MyPropertyOne = "Some text";
NewInstanceOne.MyPropertyTwo = 10;

MyGenericClass<double, Uri> NewInstanceTwo = new MyGenericClass<double, Uri>();
NewInstanceTwo.MyPropertyOne = 2.2;
NewInstanceTwo.MyPropertyTwo = new Uri("http://mycomputerknowhow.blogspot.com");

 

As you can see, when, in this case, instantiating the class, the exact type of the generic type is specified.

If MyGenericClass were a static class including all static members, you would pass the exact types as follows:

MyGenericClass<string, int>.MyPropertyOne = "string";
MyGenericClass<int, int>.MyPropertyOne = 10;

Debug.WriteLine(MyGenericClass<int, int>.MyPropertyOne);
Debug.WriteLine(MyGenericClass<string, int>.MyPropertyOne);

In the above code, classes MyGenericClass<string, int> and MyGenericClass<int, int> are in fact completely isolated from each other and can hold different values.

Though we have one class definition, since the actual types are different, MyGenericClass<string, int> and MyGenericClass<int, int> are two separate classes with different types.

Sunday, August 10, 2008

Boxing and Unboxing

Boxing simply means converting a value type to a reference type. Unboxing, on other hand, means converting a reference type to a value type.

For more information about reference types and value types, see this post.

The following is an example of boxing and unboxing:

object MyObject= 2.2; //boxing

double MyNumber=(double)MyObject;//unboxing

 

To improve the performance and maintain type safety, it is recommended to use boxing/unboxing in your code as little as possible .

Reference types and value types

Value types are the variables that store the actual values as opposed to reference types that keep a reference to memory where the data is stored.

Note: strings are reference types.

Example:

int MyValueType=123;//Value type

object MyReferenceType=new object();// reference type

Sunday, August 3, 2008

Choosing the right .Net Framework data collection

The .Net Framework includes several useful data collection classes; choosing the right one for the task at hand is greatly crucial. In the following, I will explain about some of the most useful collections available in Framework. So, you can easily decide which one to use in different situations.

These classes which are part of System.Collections namespace and System.Collections.Specialized are ArrayList, SortedList, Queue, Stack, Hashtable, BitArray, StringCollection, StringDictionary, ListDictionary, HybirdDictionary, and NameValueCollection.

ArrayList

ArrayList stores the data items of any object type in an unordered manner. Add method is used to add new data items to the collection as the last item. To add new items at a specific location, the class provides users with Insert method. You can use ArrayList numeric indexer to access each item in the collection or iterate over items. Also, you can use foreach for iteration of type object or a particular type in the case all the items are of that type (see the example for more details). Removing items from the collection is done by Remove and RemoveAt methods.

Other useful methods of ArrayList are:

Clear (empties the collection), IndexOf (specifies index of an item in the collection), Sort (sorts items in the collection), and Contains (verifies existence of an item in the collection).

Example:

Note: the example below requires System.Collections and System.Diagnostics namespaces.

ArrayList MyArrayList=new ArrayList();

MyArrayList.Add("New Item");

MyArrayList.Insert(0,"This is placed as the first item");

if (MyArrayList.Contains("New Item"))

{
    Debug.Write(MyArrayList.IndexO("New Item"))//Writes to output window. Run in debug mode.
    MyArrayList.Remove("New Item");
}

foreach (string EachItem in MyArrayList)
    System.Diagnostics.Debug.Write(EachItem )//Writes to output window. Run in debug mode.

MyArrayList.RemoveAt(0);
MyArrayList.Clear();

StringCollection

StringCollection is built to store only string items and not any other types of object. Working with StringCollection is similar to ArrayList.

Queue

The Queue stores objects in a first-in first-out manner. It means that the fist item added to the collection is the first item that is retrieved from it. Working with Queue is very simple; you can use Enqueue method to add new items, Dequeue method to retrieve items which removes the object from the collection as well, Peek method to extract the object without removing it from the collection, and Count property which returns the number of objects in the collection.

Example:

Note: the example below requires System.Collections and System.Diagnostics namespaces.

Queue MyQueue = new Queue();
MyQueue.Enqueue(2000);
MyQueue.Enqueue(new object());
MyQueue.Enqueue("Last Item");
Debug.WriteLine(MyQueue.Count);
if (MyQueue.Peek() is int)
    Debug.WriteLine(((int)MyQueue.Dequeue())+1);

Debug.WriteLine(MyQueue.Count);
MyQueue.Clear();

Stack

Stack is very similar to Queue the only difference is that Stack stores object in a last-in, first-out fashion. To work with the stored object Stack exposes Push method which adds new object to the collection, Pop method which extracts the object with removing it from the collection, Peek method which extracts the object without removing it from the collection, Clear method which removes all the objects, and Count property which shows the number of objects in the collection.

Example:

Note: the example below requires System.Collections and System.Diagnostics namespaces.

Stack MyStack = new Stack();
MyStack.Push(2000);
MyStack.Push(new object());
MyStack.Push("Last Item");
Debug.WriteLine(MyStack.Count);
if (MyStack.Peek() is string)
    Debug.WriteLine(string.Concat((string)MyStack.Pop()," is the first to be out."));

Debug.WriteLine(MyStack.Count);
MyStack.Clear();

Hashtable

Hashtable is a dictionary collection which means it keeps data in form of key and value pairs. Each collection entry is stored in one DictionaryEntry structure which in turn contains a key and a value. Key and value can be any object; a key cannot be null.  The primary purpose of dictionaries is to look up pairs.

Working with Hashtable is easy; you can use Add method to add new pairs, indexer to access each value, Remove method to remove a pair, ContainsKey method to verify existence of a key in the collection, ContainsValue to verify existence of a value in the collection, Keys property gets all the keys in the collection, Values property to get all the values in the collection, and Clear method to remove all the pairs from the collection.

Example:

Note: the example below requires System.Collections and System.Diagnostics namespaces.

Hashtable MyHashtable=new Hashtable();
MyHashtable.Add("MyKey1","MyValue");
MyHashtable.Add("MyKey2", DateTime.Now);

foreach (DictionaryEntry EachPair in MyHashtable)
    Debug.WriteLine(EachPair.Value);
if (MyHashtable.ContainsKey("MyKey1"))
    Debug.WriteLine(MyHashtable["MyKey1"]);
if (MyHashtable.ContainsValue("MyValue"))
    MyHashtable.Remove("MyKey1");

MyHashtable.Clear();

ListDictionary

ListDictionary is identical to HashTable in terms of interface but is more efficient for fewer than 10 items. See HashTable for an example on how to use this collection.

HybridDictionary

When the number of items is not known, HybirdDictionary can be used in place of HashTable or ListDictionary. HybridDictionary starts off internally as ListDictionary and converts to HashTable when the number of items in the collection gets higher than 10. HybirdDictionary also has the same interface as HashTable and ListDictionary. See HashTable for an example on how to use this collection.

OrderedDictionary

OrderedDictionary combines the power of arrays and dictionaries. In other words, working with it is much similar to HashTabe but it also provides users with properties and methods to allow items to be accessed by index. In addition to HashTable properties and methods, you can use Item property to access each item, Insert to add a new dictionary entry to a specific index in the collection, and RemoveAt to remove dictionary entries and a given index.

StringDictionary

StringDictionary is specialized dictionary collection that only stores string keys and values. Working with StringDictionary is the same as HashTable.

SortedList

Similar to Hashtable, SortedList is a dictionary collection and values are kept in key and value pairs. Therefore, all the above methods and properties for Hashtable also apply SortedList. In addition SortedList sorts the entries as soon as they are added to the collection and lets entries be accessed by index.  Note that index may change after adding or removing entries because the entries are sorted. 

Other useful methods of SortedList are IndexOfKey that returns index of a key in the collection, IndexOfValue that returns the first index of a value in the collection, GetKey that returns a key of a specific index, and GetByIndex that returns value of a specific index.

Example:

Note: the example below requires System.Collections and System.Diagnostics namespaces.

SortedList MySortedList = new SortedList();
MySortedList.Add("MyKey1","MyValue");
MySortedList.Add("MyKey2", DateTime.Now);

foreach (DictionaryEntry EachPair in MySortedList)
    Debug.WriteLine(EachPair.Value);

Debug.WriteLine(MySortedList.IndexOfKey("MyKey2"));
Debug.WriteLine(MySortedList.IndexOfValue("MyValue"));
Debug.WriteLine(MySortedList.GetKey(0));
Debug.WriteLine(MySortedList.GetByIndex(1));

if (MySortedList.ContainsKey("MyKey1"))
    Debug.WriteLine(MySortedList["MyKey1"]);
if (MySortedList.ContainsValue("MyValue"))
    MySortedList.Remove("MyKey1");

MySortedList.Clear();

BitArray

BitArray is a resizeable collection of bits and capable of performing boolean operations. To create a new instance you need to specify the length of the collection. This collection does not provide Add method; therefore, the only way to increase the capacity of it is through modification of its length property.

NameValueCollection

NameValueCollection is a dictionary collection that is able to store multiple values per key. All keys and values for this collection are of type string. To get values of a specific key, you can use GetValues method; also you can use index to access values of a key and since there can be more than one value per key, the collection returns a comma separated list of key values. You can use Add method to add new items and Clear method to remove all the items.

Example:

Note: the example below requires System.Collections.Specialized and System.Diagnostics namespaces.

NameValueCollection MyNameValueCollection = new NameValueCollection();
MyNameValueCollection.Add("FirstKey", "FirstKeyFirstValue");
MyNameValueCollection.Add("FirstKey", "FirstKeySecondValue");
MyNameValueCollection.Add("SecondKey", "SecondKeyFirstValue");
MyNameValueCollection.Add("SecondKey", "SecondKeySecondValue");
Debug.WriteLine(MyNameValueCollection.GetValues("FirstKey")[0]);
Debug.WriteLine(MyNameValueCollection.GetValues(1).Length);
Debug.WriteLine(MyNameValueCollection[1]);
MyNameValueCollection.Clear();

Monday, July 21, 2008

Serializing and deserializing objects

To serialize an object, you simply create an instance of  BinaryFormatter which is part of System.Runtime.Serialization.Formatters.Binary namespace and use Serialize or Deserialize methods.

The following example shows how an object can be serialized and deserialized. I used memory stream for my example; you can also use other kinds of stream such as FileStream. SerializingObject is the object that's being serialized. I serialize it then deserialize it to its original type which is DataTable.

Here is the example:

using(MemoryStream = new MemoryStream())
{

DataTable SerializingObject =new DataTable();

BinaryFormatter MyBinaryFormatter = new BinaryFormatter();
MyBinaryFormatter .Serialize(MyMemoryStream , SerializingObject);
MyMemoryStream .Position = 0;
DataTable DeserializingObject= (DataTable)MyBinaryFormatter.Deserialize(TableMemoryStream)

}

Saturday, July 12, 2008

Reading and Writing to Streams

In the following example, I used FileStream to explain how reading and writing to steams work.

The example is self explanatory. It reads the data from TestRead.dat and writes it to TestWrite.dat.

ReadCount is 0 when Read has reached the end of the file; otherwise it is 1<=ReadCount<=100. ReadCount can change every time that Read method is called in the loop.

Buffer length can be modified but please note that it has to be able to accommodate the number of bytes returned by Read method.

 

using (FileStream ReadStream = new FileStream("c:\\TestRead.dat", FileMode.Open))
            {
                using (FileStream WriteStream = new FileStream("c:\\TestWrite.dat", FileMode.Create))
                {
                    byte[] Buffer = new byte[101];

                    int ReadCount = 0;
                    do
                    {
                        ReadCount = ReadStream.Read(Buffer, 0, 100);
                        WriteStream.Write(Buffer, 0, ReadCount);

                    } while (ReadCount != 0);
                }
            }

Tuesday, April 29, 2008

Classes vs Structures

Ever wondered what are the differences between classes and structures and when you should use which one. According to Donis Marshall in his book called Visual C# 2005: The Language he mentions:

"Structures are lightweight classes. Because structures reside on the stack, keep them small. Do not cache large objects on the stack. The implementation of structures in C# enforces the policy of using a structure as lightweight class. The following list details the differences between structures and classes:

  • Structures are sealed and cannot be inherited.
  • Structures cannot inherit classes and other structures
  • Structure implicitly inherits from System.ValueType
  • The default constructor of a structure cannot be replaced by a custom constructor.
  • Structures do not have destructors.
  • Field initialization is not allowed. Const members of a structure can be initialized. "

Monday, February 18, 2008

Converting SQL server Bit fields to Yes/No values

Usually Yes/No values are saved in the database using bit data type. The problem with this kind of design is that when the table is bound a Visual Studio control, will show 0/1, instead of yes/no. For example, imagine the situation where programmer needs to save whether or not a user should be contacted, in the database and a repeater control will display that on a web page later on. The result can be something like the following:

Call me for more information: 0

Which would mean: do not contact the person. Obviously, it's not the best design; First of all it's not user-friendly at all and secondly, some people don't know 0 means false or no.

The following SQL server user-defined function can be used to do the conversion.

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Create FUNCTION dbo.CastBitToYesNo
(
@value bit
)
RETURNS varchar(20)
AS
BEGIN
Declare @ReturnValue varchar(20)

If @value=1
Set @ReturnValue='Yes'
Else
Set @ReturnValue='No'

RETURN @ReturnValue

END
GO

Here is an example of the use of the function:

Select CastBitToYesNo(MyBitField) as YesNoField from MyTable

Tuesday, February 5, 2008

Evaluating a reference type variable in terms of type before casting.

To evaluate a reference type variable, simply use "is" keyword. It will tell you whether or not a variable is capable of being cast to another type. If you are not sure about the type of the variable before casting it, you should use "is".

For example if you are iterating through the web controls, you can utilize the following code:

for each (control Ctrl in Page.Form.Controls)
{
  if (Ctrl is DropDownList)
    DropDownList Ddl =(DropDownList)Ctrl;
}

In the above example, if you don't use "is" keyword, application tries to cast other types of controls to DropDownList and obviously it will throw a cast exception.

Sunday, December 23, 2007

There is already an open DataReader associated with this Connection which must be closed first

Some time ago I decide to query the database multiple times using only one connection and some Datareaders. My logic was that I can reduce the server load by doing so.

Having multiple DataReaders on one Database connection is not, in fact, practical. Each Datareader can be used only with one connection and a new conncetion is needed for the next Datareader.

Reading Only Date Section of Datetime Fields values.

Issue

Microsoft SQL Server stores date values in fields using datetime data type. Most programmers only need the date section while time is always attatched to the date when it's saved. When the value is read, time shows up right beside the date section.

Solution

Use the following formatting for the column where the date values will be shown:

DataFormatString="{0:MM/dd/YYYY}";

Also remember to disable html encoding for the above field:

HtmlEncode=false;

Wednesday, November 7, 2007

JavaScript Onload event on Visual Studio 2005 Content pages.

Issue

If you create Master/Content page setup in Visual Studio 2005, you quickly realize that Content pages do not include essential HTML tags such as Head and body. Therefore, Onload event of JavaScript cannot be used on the body tag.

Workaround

Use the following in you Content page:

<script type="text/javascript" >
  window.onload=MyFunction;
< /script>

MyFunction is a placeholder for your function name.

Note: there are no parentheses preceding the function name. If parentheses are used in front of the function name, user will recieve JavaScript runtime error "Not implemented".