.NET Framework 2.2 has 3 types of “Timer” control, they are
a) System.Windows.Form.Timer: This is probably the mostly used “Timer” control, we can add it by drag and drop form the toolbox.. This type of timer requires that a user interface message pump is operating[this type of timer corresponds to the WM_TIMER message used in Windows SDK programming, and is implemented by this Timer class] , and all timer events are handled on the UI thread, so upon “Timer_Tick” event, if we need to do modify the UI, then this type of Timer is appropriate[ if accuracy and UI responsiveness is not a concern ].
b) System.Timers.Timer: This type of timer can be used in any type of .NET program, including Windows Forms programs, Windows Services, ASP.NET programs, console applications, Web services, and others. The timer works in much the same way as does the Windows Forms timer, but does not require the Windows message pump. Other than that, the primary difference between server timers and Windows Forms timers is that the event handlers for server timers execute on thread pool threads. This makes it possible to maintain a responsive user interface even if the event handler takes a long time to execute.
c) System.Threading.Timer: This timer class implements a simple lightweight timer that uses callback functions and is served by thread-pool threads. This type of timer is not a component like the other two. It also has fewer features. It has the benefit, though, of not going through the event system, but rather making direct callbacks. When we create the timer, we specify the callback method, the time to wait before the first time the callback is executed, and the amount of time (period) between calls.
As per the MSDN documentation type b i.e. Timers,Timer is the most accurate timer, I have written a “Test application” to do various test, and I have found the timers [I have tested with all 3 type of timers ] have an accuracy up-to 10 milliseconds, although it has been mentioned in the MSDN documentation that System.Timers has accuracy of 55 millisecond.
If anybody want to play with the TestApplication please download it from "MS Developer's group, kolkata" site [ http://groups.msn.com/Kolkatanet/general.msnw?action=get_message&mview=0&ID_Message=2381 ]
To run the Test application, select a Timer type, specify the interval value( in millisecond ), and hit on the “Start” button, on each timer_tick, the handler/callback routine will print the current time, stop the timer using the “Stop” button.
Important note: Since “tick” event of Timer.Timer and Threading.Timer get handled by the thread-pool thread, so accessing the UI thread form the event-handlers or the callback method will raise exception , which is why I have set the “CheckForIllegalCrossThreadCalls” as false.
Sunday, November 05, 2006
Saturday, September 16, 2006
Assembly reference in .NET 2.0
There are lot of new things in VS 2005( aka .NET 2.0 ), I was doing some research on the referencing, versioning assemblies and I found there are lot of new features... I want to talk about two striking features on this ground ....
1) Adding an exe as reference: In .NET 1.1 we could only add reference of Library assembly( dll ), so we had to make sure that all the sharing code should be in a dll. .NET 2.2 allows us to add
a) Library assembly( dll ) and also b) Application assembly( exe ). So, now we can add any exe as a reference to our assembly and we can access all the public class::public methods/properties of that assembly, and another important thing is that the referenced exe will also run in the same app domain of the application( the application which has added this reference ).
I think this feature can be useful at times, but at the same time we should use Library assembly to share codebase.( the old and gold way -:) )
2) Resolving type name conflicts in a new way( new feature 'alias' ): The second feature is more interesting ... consider the following case ...
we are writing an application which will add two third party dll, say name of those dlls are ThirdParty1.dll( namespace is ThirdParty1) and ThirdParty2.dll( namespace is ThirdParty2) and both the dll has a public class named Customer. In our win application( in a class ) we have added both the namespace in the Using directive.
now if we write something like this
Customer c = new Customer();
Compiler will raise an error since Customer is defined in both ThirdParty1.dll::ThirdParty1 namespace and ThirdParty2.dll::ThirdParty2 namespace, so it could not resolve the class definition since it is ambiguous.
To fix this problem we should rewrite our code as ...........
ThirdParty1.Customer c = new ThirdParty1.Customer();<>
The above behavior is same in .NET 1.1 and .NET 2.0.
Now, let us make the situation little more complex .. how if both the dlls have the same namespace say both the dlls have "ThirdParty" as namespace.
Now in the application if we write ..... Customer c = new Customer();
In .NET 1.1 there should not be any error, and we can see in the IDE( VS 2003 ) that whole line is underlined with blue color, and it says that the Customer class is defined in multiple places and it is taking the definition from one of them.
I found that it takes the "Customer" definition by the order of assembly adding, like if we add ThidParty1 first then it will be using ThirdParty1::Customer.( does anybody has different idea )
In .NET 2.0 the code< c =" new"> will raise an error, it does not follow the path of .NET 1.1, so how to solve this issue ? To solve this issue we have to do the following ...
a) In VS 2005 every reference has an alias( new feature in 2.0 ) and by default the alias is "Global" so first we have to change the alias of one the referenced assembly, say let us change the alias of ThidParty1 as "MyThidParty".( Select the reference from the solution explorer and click F4 to see the properties of the assembly and you can find the alias here )
b) We need to add the following line [ extern alias MyThidParty;] before writing any using directive, .NET 2.0 compiler always use "Global" alias, not any other alias, so to use any other assembly which has different alias we need tell the compiler using the above statement.
Now we are all done ..
Customer c = new Customer(); will use the definition from ThirdParty2 assembly( the global aliased one ). To create an instance of "Customer" class which is defined in the ThirdParty1 we have to create the instance in this manner ----
MyThirdParty::ThirdParty.Customer c = new MyThirdParty::ThirdParty.Customer(); [aliasname::namespace.classname ]
1) Adding an exe as reference: In .NET 1.1 we could only add reference of Library assembly( dll ), so we had to make sure that all the sharing code should be in a dll. .NET 2.2 allows us to add
a) Library assembly( dll ) and also b) Application assembly( exe ). So, now we can add any exe as a reference to our assembly and we can access all the public class::public methods/properties of that assembly, and another important thing is that the referenced exe will also run in the same app domain of the application( the application which has added this reference ).
I think this feature can be useful at times, but at the same time we should use Library assembly to share codebase.( the old and gold way -:) )
2) Resolving type name conflicts in a new way( new feature 'alias' ): The second feature is more interesting ... consider the following case ...
we are writing an application which will add two third party dll, say name of those dlls are ThirdParty1.dll( namespace is ThirdParty1) and ThirdParty2.dll( namespace is ThirdParty2) and both the dll has a public class named Customer. In our win application( in a class ) we have added both the namespace in the Using directive.
now if we write something like this
Customer c = new Customer();
Compiler will raise an error since Customer is defined in both ThirdParty1.dll::ThirdParty1 namespace and ThirdParty2.dll::ThirdParty2 namespace, so it could not resolve the class definition since it is ambiguous.
To fix this problem we should rewrite our code as ...........
ThirdParty1.Customer c = new ThirdParty1.Customer();<>
The above behavior is same in .NET 1.1 and .NET 2.0.
Now, let us make the situation little more complex .. how if both the dlls have the same namespace say both the dlls have "ThirdParty" as namespace.
Now in the application if we write ..... Customer c = new Customer();
In .NET 1.1 there should not be any error, and we can see in the IDE( VS 2003 ) that whole line is underlined with blue color, and it says that the Customer class is defined in multiple places and it is taking the definition from one of them.
I found that it takes the "Customer" definition by the order of assembly adding, like if we add ThidParty1 first then it will be using ThirdParty1::Customer.( does anybody has different idea )
In .NET 2.0 the code< c =" new"> will raise an error, it does not follow the path of .NET 1.1, so how to solve this issue ? To solve this issue we have to do the following ...
a) In VS 2005 every reference has an alias( new feature in 2.0 ) and by default the alias is "Global" so first we have to change the alias of one the referenced assembly, say let us change the alias of ThidParty1 as "MyThidParty".( Select the reference from the solution explorer and click F4 to see the properties of the assembly and you can find the alias here )
b) We need to add the following line [ extern alias MyThidParty;] before writing any using directive, .NET 2.0 compiler always use "Global" alias, not any other alias, so to use any other assembly which has different alias we need tell the compiler using the above statement.
Now we are all done ..
Customer c = new Customer(); will use the definition from ThirdParty2 assembly( the global aliased one ). To create an instance of "Customer" class which is defined in the ThirdParty1 we have to create the instance in this manner ----
MyThirdParty::ThirdParty.Customer c = new MyThirdParty::ThirdParty.Customer(); [aliasname::namespace.classname ]
Sunday, May 21, 2006
C# OR VB.NET
Few days back (unfortunately) I got involved in a debate with an gentleman when we were discussing over .NET programming, and he found that I am kind of biased on C#, so he asked me "Why did you choose C# as your programming language, not VB.NET ?" and then we both tried to prove our points for next half an hour.
I am sure this is the most common debate among .NET programmers( since VB.NET and C# are most dominant language in .NET platform).. the C# programmers cite heaps of points to prove C# is best language so far and VB.NET programmers follow the same route to prove that C# programmers are all unrealistic etc etc.
The mostly used points come in the discussion( read debate ) are
1) Programming style(syntax and semantics): C# is rule based<>, VB is verbose but at the same time gives flexibility to the developers.
2) Availability of futures: Like VB.NET has a feature "X" which is absent in C# and vice versa.
3) Performance of MSIL : It is believed that C# code is faster than VB.NET code( I am not sure whether it is just a myth or not ) and VB.NET group think it just a MYTH.
4) IDE support : For example when we need to define a property, in VB.NET all we need to do is write "property" and a hit on enter key, the IDE write the get and set for us.
5)Additional features : For example C# allow us to write unmanaged code and most importantly we can use "POINTER".
May be some more points which I am not aware off.
Honestly speaking there are hardly any realistic difference between these two language, I have personally worked on both the languages, and to be very frank only difference I have found is the programming style, that's all. Both the language use same class library comes with .NET framework, same OOP features supported, same runtime, same garbage collector, like in the earlier days we used to compare between VB and C++ programmers and it is a truth that, C++ programmers(mostly) looked down upon the VB programmer, to them VB programmers don't know OOP, they don't know design patterns, VB code is slow etc etc.
But that's not the case today, VB.NET allow to do almost all the features supported by C#, so why still differentiate between these two language ?
So, here comes another turn ...if there is no difference at all how to choose one of them ? As we commonly say VB programmer will choose VB.NET and C++/Java programmer will choose C#, but let us see how far this statement is correct ? If you go by a statistics( published by Evans Data Corp, Santa Cruz ), it says that C# is most popular( and used ) language in the .NET platform, VB.NET comes second, which means there are lot of C++ and Java programmer shifted to .NET environment, well this is partly true as the statistics also revels that a large part of C# developers are x VB developer.
Let us do an introspection, consider you have to start a new project and you are the project leader and you are free to choose a language( VB.NET or C# ) which one will you choose and why ? In deed this is an interesting question and as a matter of fact, I think most of the time we choose a language not thinking much, so the point here is....what are the factors a project leader should consider before choosing a language in the .NET domain ..
so far I can think of the following points,
1) Team strength : Considering there is an excellent team of VB.NET or C#.
2) Any special features needed : Say if we feel we can not develop a solution of the specified problem without "pointer" then we need to use C#.
3) Preference of the Software Architect: Honestly speaking most of the software architects has C++/Java background(well, that's what I have seen, may be my view is biased ), so they would prefer to work on a language which has C++/Java flavor, C# will be simple choice for them, but in that case may be the developers need to train C#.
Is there anything else ?? ... , please update with your comments.
I will finish this article with one confusion .. why only C# was submitted to the ECMA as an international standard, if Microsoft really think VB.NET was/will be a strategic language in long run, why don't they submit it ? anybody has any clue ??
I am sure this is the most common debate among .NET programmers( since VB.NET and C# are most dominant language in .NET platform).. the C# programmers cite heaps of points to prove C# is best language so far and VB.NET programmers follow the same route to prove that C# programmers are all unrealistic etc etc.
The mostly used points come in the discussion( read debate ) are
1) Programming style(syntax and semantics): C# is rule based<>, VB is verbose but at the same time gives flexibility to the developers.
2) Availability of futures: Like VB.NET has a feature "X" which is absent in C# and vice versa.
3) Performance of MSIL : It is believed that C# code is faster than VB.NET code( I am not sure whether it is just a myth or not ) and VB.NET group think it just a MYTH.
4) IDE support : For example when we need to define a property, in VB.NET all we need to do is write "property"
5)Additional features : For example C# allow us to write unmanaged code and most importantly we can use "POINTER".
May be some more points which I am not aware off.
Honestly speaking there are hardly any realistic difference between these two language, I have personally worked on both the languages, and to be very frank only difference I have found is the programming style, that's all. Both the language use same class library comes with .NET framework, same OOP features supported, same runtime, same garbage collector, like in the earlier days we used to compare between VB and C++ programmers and it is a truth that, C++ programmers(mostly) looked down upon the VB programmer, to them VB programmers don't know OOP, they don't know design patterns, VB code is slow etc etc.
But that's not the case today, VB.NET allow to do almost all the features supported by C#, so why still differentiate between these two language ?
So, here comes another turn ...if there is no difference at all how to choose one of them ? As we commonly say VB programmer will choose VB.NET and C++/Java programmer will choose C#, but let us see how far this statement is correct ? If you go by a statistics( published by Evans Data Corp, Santa Cruz ), it says that C# is most popular( and used ) language in the .NET platform, VB.NET comes second, which means there are lot of C++ and Java programmer shifted to .NET environment, well this is partly true as the statistics also revels that a large part of C# developers are x VB developer.
Let us do an introspection, consider you have to start a new project and you are the project leader and you are free to choose a language( VB.NET or C# ) which one will you choose and why ? In deed this is an interesting question and as a matter of fact, I think most of the time we choose a language not thinking much, so the point here is....what are the factors a project leader should consider before choosing a language in the .NET domain ..
so far I can think of the following points,
1) Team strength : Considering there is an excellent team of VB.NET or C#.
2) Any special features needed : Say if we feel we can not develop a solution of the specified problem without "pointer" then we need to use C#.
3) Preference of the Software Architect: Honestly speaking most of the software architects has C++/Java background(well, that's what I have seen, may be my view is biased ), so they would prefer to work on a language which has C++/Java flavor, C# will be simple choice for them, but in that case may be the developers need to train C#.
Is there anything else ?? ... , please update with your comments.
I will finish this article with one confusion .. why only C# was submitted to the ECMA as an international standard, if Microsoft really think VB.NET was/will be a strategic language in long run, why don't they submit it ? anybody has any clue ??
Thursday, May 04, 2006
Floating point number .. an interesting issue
Last night I was doing some work and came across a very interesting situation, I have simulated the problem with a simple example, consider I have written a class which has 3 function with the same name , all of them takes one floating point number as an argument.
class MyClass {
void Display( decimal number ) { Console.WriteLine( "{0} {1}", number.GetType(), number ); }
void Display( float number ) { Console.WriteLine( "{0} {1}", number.GetType(), number ); }
void Display( double number ) { Console.WriteLine( "{0} {1}", number.GetType(), number ); }
static void Main( ) { MyClass m = new MyClass(); m.Display( 1000.90 ); Console.ReadLine(); } }
Here, the question is which "Display" function will be get called ? I have tried out lot of numbers and I have found that every time "Display( double number)" get called.
then I have looked into the IL, it looks like the following line ..
IL_0007: ldc.r8 1000.9IL_0010: callvirt instance float64 QuestionsTest.MyClass::Display(float64)
which means it will call the routine which takes 64 bit float, i.e. double, I was wondering why does it happen .... then I have found something form the MSDN library which says "By default, a real numeric literal on the right-hand side of the assignment operator is treated as double, Therefore, to initialize a float variable, use the suffix f or F, and to initialize a decimal variable use the suffix m or M".
I have modified the main routine in the following manner ....
m.Display( 1000.90 );
m.Display( 1000.90f );
m.Display( 1000.90m );
and I found the following output ..
System.Double 1000.9
System.Single 1000.9
System.Decimal 1000.90
So the conclusion is when we have to write routines with same name and will take floating point number as argument we have to be little cautious when we will call them.
Comments are welcome.
class MyClass {
void Display( decimal number ) { Console.WriteLine( "{0} {1}", number.GetType(), number ); }
void Display( float number ) { Console.WriteLine( "{0} {1}", number.GetType(), number ); }
void Display( double number ) { Console.WriteLine( "{0} {1}", number.GetType(), number ); }
static void Main( ) { MyClass m = new MyClass(); m.Display( 1000.90 ); Console.ReadLine(); } }
Here, the question is which "Display" function will be get called ? I have tried out lot of numbers and I have found that every time "Display( double number)" get called.
then I have looked into the IL, it looks like the following line ..
IL_0007: ldc.r8 1000.9IL_0010: callvirt instance float64 QuestionsTest.MyClass::Display(float64)
which means it will call the routine which takes 64 bit float, i.e. double, I was wondering why does it happen .... then I have found something form the MSDN library which says "By default, a real numeric literal on the right-hand side of the assignment operator is treated as double, Therefore, to initialize a float variable, use the suffix f or F, and to initialize a decimal variable use the suffix m or M".
I have modified the main routine in the following manner ....
m.Display( 1000.90 );
m.Display( 1000.90f );
m.Display( 1000.90m );
and I found the following output ..
System.Double 1000.9
System.Single 1000.9
System.Decimal 1000.90
So the conclusion is when we have to write routines with same name and will take floating point number as argument we have to be little cautious when we will call them.
Comments are welcome.
Wednesday, April 05, 2006
Ordered HashTable
Yesterday one of my colleague was asking me whether there is any ordered HashTable available in the .NET framework, as we all know HashTable is not an ordered list( like Array or ArrayList ), and so far my knowledge goes there is no such collection available which is ordered hash.
So, the probelm was like this ... consider the following code ...
Hashtable mAnotherHashTbl = new Hashtable(); mAnotherHashTbl.Add( "A", "AAA" ); mAnotherHashTbl.Add( "B", "BBB" ); mAnotherHashTbl.Add( "C", "CCC" ); mAnotherHashTbl.Add( "D", "DDD" ); mAnotherHashTbl.Add( "E", "EEE" );
and now if you loop thru the hash table like this ...
foreach( string key in mAnotherHashTbl.Keys ) { Console.WriteLine( mAnotherHashTbl[ key ].ToString()); }
you may( will ) not see AAA, BBB, CCC, DDD, EEE. in this order.
My friend apparently found a simple solution, took a HashTable and also an ArrayList and store all the keys in the ArrayList and when you have to enumerate the HashTable .. just loop thru the ArrayList and get the value from the HashTable using HashTable [ key ] .
I personally think this is the only solution available to have an ordered HashTable, we need an array/arraylist and a HashTable.
I tried to develop a class (OrderedHashTable) which encapsulate the above idea,( I have thought develop one long time back, being lazy by nature it took me this long time -:) ) so from the user's point view this collection will behave exactly like a HashTable but this it will be ordered.
Since I don't found any ways to attach the code with this blog hence I am coping the whole code base( OrderedHashTable class) as part of the blog .. which may look ugly .. if anybody feel interested I would suggest copy the code from here and paste it in a IDE and then have a look.
using System;
using System.Collections;
namespace Neo.Rnd.OrderedHashTable
{ /// /// Summary description for OrderedHashTable. ///
public class OrderedHashTable:ICollection,IDictionary
{
Hashtable m_HashObjects; ArrayList m_ArrObjects;
public OrderedHashTable()
{
m_HashObjects = new Hashtable();
m_ArrObjects = new ArrayList();
}
#region ICollection Members
public bool IsSynchronized { get { // TODO: Add OrderedHashTable.IsSynchronized getter implementation return false; } }
public void CopyTo(Array array, int index) { // TODO: Add OrderedHashTable.CopyTo implementation }
public object SyncRoot { get { // TODO: Add OrderedHashTable.SyncRoot getter implementation return null; } }
#endregion
#region IEnumerable Members
public IEnumerator GetEnumerator() { // TODO: Add OrderedHashTable.GetEnumerator implementation return null; }
#endregion
#region IDictionary Members
public bool IsReadOnly { get { // TODO: Add OrderedHashTable.IsReadOnly getter implementation return false; } }
IDictionaryEnumerator System.Collections.IDictionary.GetEnumerator() { // TODO: Add OrderedHashTable.System.Collections.IDictionary.GetEnumerator implementation return null; }
public object this[object key] { get { return m_HashObjects[ key ]; } set { // TODO: Add OrderedHashTable.this setter implementation } }
public void Remove( object key ) { m_HashObjects.Remove( key ); int index = GetIndexByKey( key ); m_ArrObjects.RemoveAt( index ); }
public bool Contains( object key ) { return( m_HashObjects.Contains( key )); }
public void Clear() { m_HashObjects.Clear(); m_ArrObjects.Clear(); }
public ICollection Values { get { ArrayList retList = new ArrayList (); for( int i = 0; i < m_ArrObjects.Count; i++ ) { retList.Add ( ((DictionaryEntry)m_ArrObjects[i]).Value ); } return retList; } }
public void Add( object key, object val ) { m_HashObjects.Add( key, val ); m_ArrObjects.Add( new DictionaryEntry( key, val ) ); }
public ICollection Keys { get { ArrayList retList = new ArrayList (); for( int i = 0; i < m_ArrObjects.Count; i++ ) { retList.Add ( ((DictionaryEntry)m_ArrObjects[ i ]).Key ); } return retList; } }
public bool IsFixedSize { get { // TODO: Add OrderedHashTable.IsFixedSize getter implementation return false; } }
#endregion
#region ICollection Members
public int Count { get { return m_ArrObjects.Count; } }
#endregion
#region Helper routines
private int GetIndexByKey( object key )
{
for( int i = 0; i < m_ArrObjects.Count; i++ )
{
object currKey = ((DictionaryEntry) m_ArrObjects[ i ]).Key;
if( currKey.Equals( key ))
{
return i;
}
}
return -1;
}
#endregion
}
}
So, the probelm was like this ... consider the following code ...
Hashtable mAnotherHashTbl = new Hashtable(); mAnotherHashTbl.Add( "A", "AAA" ); mAnotherHashTbl.Add( "B", "BBB" ); mAnotherHashTbl.Add( "C", "CCC" ); mAnotherHashTbl.Add( "D", "DDD" ); mAnotherHashTbl.Add( "E", "EEE" );
and now if you loop thru the hash table like this ...
foreach( string key in mAnotherHashTbl.Keys ) { Console.WriteLine( mAnotherHashTbl[ key ].ToString()); }
you may( will ) not see AAA, BBB, CCC, DDD, EEE. in this order.
My friend apparently found a simple solution, took a HashTable and also an ArrayList and store all the keys in the ArrayList and when you have to enumerate the HashTable .. just loop thru the ArrayList and get the value from the HashTable using HashTable [ key ] .
I personally think this is the only solution available to have an ordered HashTable, we need an array/arraylist and a HashTable.
I tried to develop a class (OrderedHashTable) which encapsulate the above idea,( I have thought develop one long time back, being lazy by nature it took me this long time -:) ) so from the user's point view this collection will behave exactly like a HashTable but this it will be ordered.
Since I don't found any ways to attach the code with this blog hence I am coping the whole code base( OrderedHashTable class) as part of the blog .. which may look ugly .. if anybody feel interested I would suggest copy the code from here and paste it in a IDE and then have a look.
using System;
using System.Collections;
namespace Neo.Rnd.OrderedHashTable
{ ///
public class OrderedHashTable:ICollection,IDictionary
{
Hashtable m_HashObjects; ArrayList m_ArrObjects;
public OrderedHashTable()
{
m_HashObjects = new Hashtable();
m_ArrObjects = new ArrayList();
}
#region ICollection Members
public bool IsSynchronized { get { // TODO: Add OrderedHashTable.IsSynchronized getter implementation return false; } }
public void CopyTo(Array array, int index) { // TODO: Add OrderedHashTable.CopyTo implementation }
public object SyncRoot { get { // TODO: Add OrderedHashTable.SyncRoot getter implementation return null; } }
#endregion
#region IEnumerable Members
public IEnumerator GetEnumerator() { // TODO: Add OrderedHashTable.GetEnumerator implementation return null; }
#endregion
#region IDictionary Members
public bool IsReadOnly { get { // TODO: Add OrderedHashTable.IsReadOnly getter implementation return false; } }
IDictionaryEnumerator System.Collections.IDictionary.GetEnumerator() { // TODO: Add OrderedHashTable.System.Collections.IDictionary.GetEnumerator implementation return null; }
public object this[object key] { get { return m_HashObjects[ key ]; } set { // TODO: Add OrderedHashTable.this setter implementation } }
public void Remove( object key ) { m_HashObjects.Remove( key ); int index = GetIndexByKey( key ); m_ArrObjects.RemoveAt( index ); }
public bool Contains( object key ) { return( m_HashObjects.Contains( key )); }
public void Clear() { m_HashObjects.Clear(); m_ArrObjects.Clear(); }
public ICollection Values { get { ArrayList retList = new ArrayList (); for( int i = 0; i < m_ArrObjects.Count; i++ ) { retList.Add ( ((DictionaryEntry)m_ArrObjects[i]).Value ); } return retList; } }
public void Add( object key, object val ) { m_HashObjects.Add( key, val ); m_ArrObjects.Add( new DictionaryEntry( key, val ) ); }
public ICollection Keys { get { ArrayList retList = new ArrayList (); for( int i = 0; i < m_ArrObjects.Count; i++ ) { retList.Add ( ((DictionaryEntry)m_ArrObjects[ i ]).Key ); } return retList; } }
public bool IsFixedSize { get { // TODO: Add OrderedHashTable.IsFixedSize getter implementation return false; } }
#endregion
#region ICollection Members
public int Count { get { return m_ArrObjects.Count; } }
#endregion
#region Helper routines
private int GetIndexByKey( object key )
{
for( int i = 0; i < m_ArrObjects.Count; i++ )
{
object currKey = ((DictionaryEntry) m_ArrObjects[ i ]).Key;
if( currKey.Equals( key ))
{
return i;
}
}
return -1;
}
#endregion
}
}
Subscribe to:
Posts (Atom)