1 // HashtableTest.cs - NUnit Test Cases for the System.Collections.Hashtable class
\r
4 // (C) Ximian, Inc. http://www.ximian.com
\r
9 using System.Collections;
\r
12 using System.Runtime.Serialization;
\r
13 using System.Runtime.Serialization.Formatters;
\r
14 using System.Runtime.Serialization.Formatters.Binary;
\r
16 using NUnit.Framework;
\r
20 namespace MonoTests.System.Collections {
\r
23 /// <summary>Hashtable test.</summary>
\r
25 public class HashtableTest : Assertion {
\r
28 public void TestCtor1() {
\r
29 Hashtable h = new Hashtable();
\r
30 AssertNotNull("No hash table", h);
\r
34 public void TestCtor2() {
\r
36 bool errorThrown = false;
\r
38 Hashtable h = new Hashtable((IDictionary) null);
\r
39 } catch (ArgumentNullException) {
\r
42 Assert("null hashtable error not thrown",
\r
46 string[] keys = {"this", "is", "a", "test"};
\r
47 char[] values = {'a', 'b', 'c', 'd'};
\r
48 Hashtable h1 = new Hashtable();
\r
49 for (int i = 0; i < keys.Length; i++) {
\r
50 h1[keys[i]] = values[i];
\r
52 Hashtable h2 = new Hashtable(h1);
\r
53 for (int i = 0; i < keys.Length; i++) {
\r
54 AssertEquals("No match for key " + keys[i],
\r
55 values[i], h2[keys[i]]);
\r
61 [ExpectedException (typeof (ArgumentOutOfRangeException))]
\r
62 public void TestCtor3 ()
\r
64 Hashtable h = new Hashtable ();
\r
65 Hashtable hh = new Hashtable (h, Single.NaN);
\r
69 [ExpectedException (typeof (ArgumentException))]
\r
70 public void TestCtor4 ()
\r
72 Hashtable ht = new Hashtable (Int32.MaxValue, 0.1f, null, null);
\r
76 public void TestCtor5 ()
\r
78 // tests if negative capacity throws exception
\r
80 Hashtable ht = new Hashtable (-10, 0.1f, null, null);
\r
81 Assert("must throw ArgumentOutOfRange exception, param: capacity", false);
\r
82 } catch (ArgumentOutOfRangeException e) {
\r
83 Assert("ParamName is not capacity", e.ParamName == "capacity");
\r
86 // tests if loadFactor out of range throws exception (low)
\r
88 Hashtable ht = new Hashtable (100, 0.01f, null, null);
\r
89 Assert("must throw ArgumentOutOfRange exception, param: loadFactor, too low value", false);
\r
90 } catch (ArgumentOutOfRangeException e)
\r
92 Assert("ParamName is not loadFactor",e.ParamName == "loadFactor");
\r
95 // tests if loadFactor out of range throws exception (high)
\r
98 Hashtable ht = new Hashtable (100, 2f, null, null);
\r
99 Assert("must throw ArgumentOutOfRange exception, param: loadFactor, too high value", false);
\r
101 catch (ArgumentOutOfRangeException e)
\r
103 Assert("ParamName is not loadFactor", e.ParamName == "loadFactor");
\r
108 // TODO - Ctors for capacity and load (how to test? any access?)
\r
109 // TODO - Ctors with IComparer, IHashCodeProvider, Serialization
\r
112 public void TestCount() {
\r
113 Hashtable h = new Hashtable();
\r
114 AssertEquals("new table - count zero", 0, h.Count);
\r
116 for (int i = 1; i <= max; i++) {
\r
118 AssertEquals("Count wrong for " + i,
\r
121 for (int i = 1; i <= max; i++) {
\r
123 AssertEquals("Count shouldn't change at " + i,
\r
129 public void TestIsFixedSize() {
\r
130 Hashtable h = new Hashtable();
\r
131 AssertEquals("hashtable not fixed by default",
\r
132 false, h.IsFixedSize);
\r
133 // TODO - any way to get a fixed-size hashtable?
\r
136 public void TestIsReadOnly() {
\r
137 Hashtable h = new Hashtable();
\r
138 AssertEquals("hashtable not read-only by default",
\r
139 false, h.IsReadOnly);
\r
140 // TODO - any way to get a read-only hashtable?
\r
144 public void TestIsSynchronized ()
\r
146 Hashtable h = new Hashtable ();
\r
147 Assert ("hashtable not synched by default", !h.IsSynchronized);
\r
149 Hashtable h2 = Hashtable.Synchronized (h);
\r
150 Assert ("hashtable should by synched", h2.IsSynchronized);
\r
152 Hashtable h3 = (Hashtable) h2.Clone ();
\r
153 Assert ("Cloned Hashtable should by synched", h3.IsSynchronized);
\r
157 public void TestItem() {
\r
159 bool errorThrown = false;
\r
161 Hashtable h = new Hashtable();
\r
162 Object o = h[null];
\r
163 } catch (ArgumentNullException e) {
\r
164 errorThrown = true;
\r
165 AssertEquals("ParamName is not \"key\"", "key", e.ParamName);
\r
167 Assert("null hashtable error not thrown",
\r
170 // TODO - if read-only and/or fixed-size is possible,
\r
171 // test 'NotSupportedException' here
\r
174 Hashtable h = new Hashtable();
\r
176 for (int i = 1; i <= max; i++) {
\r
178 AssertEquals("value wrong for " + i,
\r
185 public void TestKeys() {
\r
186 string[] keys = {"this", "is", "a", "test"};
\r
187 string[] keys2 = {"new", "keys"};
\r
188 char[] values1 = {'a', 'b', 'c', 'd'};
\r
189 char[] values2 = {'e', 'f', 'g', 'h'};
\r
190 ICollection keysReference, keysReference2;
\r
191 Hashtable h1 = new Hashtable();
\r
192 for (int i = 0; i < keys.Length; i++) {
\r
193 h1[keys[i]] = values1[i];
\r
195 AssertEquals("keys wrong size",
\r
196 keys.Length, h1.Keys.Count);
\r
197 for (int i = 0; i < keys.Length; i++) {
\r
198 h1[keys[i]] = values2[i];
\r
200 AssertEquals("keys wrong size 2",
\r
201 keys.Length, h1.Keys.Count);
\r
203 // MS .NET Always returns the same reference when calling Keys property
\r
204 keysReference = h1.Keys;
\r
205 keysReference2 = h1.Keys;
\r
206 AssertEquals("keys references differ", keysReference, keysReference2);
\r
208 for (int i = 0; i < keys2.Length; i++)
\r
210 h1[keys2[i]] = values2[i];
\r
212 AssertEquals("keys wrong size 3",
\r
213 keys.Length+keys2.Length, h1.Keys.Count);
\r
214 AssertEquals("keys wrong size 4",
\r
215 keys.Length+keys2.Length, keysReference.Count);
\r
220 public void TestValues() {
\r
221 string[] keys = {"this", "is", "a", "test"};
\r
222 char[] values1 = {'a', 'b', 'c', 'd'};
\r
223 char[] values2 = {'e', 'f', 'g', 'h'};
\r
224 Hashtable h1 = new Hashtable();
\r
225 for (int i = 0; i < keys.Length; i++) {
\r
226 h1[keys[i]] = values1[i];
\r
228 AssertEquals("values wrong size",
\r
229 keys.Length, h1.Values.Count);
\r
230 for (int i = 0; i < keys.Length; i++) {
\r
231 h1[keys[i]] = values2[i];
\r
233 AssertEquals("values wrong size 2",
\r
234 keys.Length, h1.Values.Count);
\r
236 // MS .NET Always returns the same reference when calling Values property
\r
237 ICollection valuesReference1 = h1.Values;
\r
238 ICollection valuesReference2 = h1.Values;
\r
239 AssertEquals("values references differ", valuesReference1, valuesReference2);
\r
243 public void TestAdd() {
\r
245 bool errorThrown = false;
\r
247 Hashtable h = new Hashtable();
\r
248 h.Add(null, "huh?");
\r
249 } catch (ArgumentNullException e) {
\r
250 errorThrown = true;
\r
251 AssertEquals("ParamName is not 'key'", "key", e.ParamName);
\r
253 Assert("null add error not thrown",
\r
257 bool errorThrown = false;
\r
259 Hashtable h = new Hashtable();
\r
262 } catch (ArgumentException) {
\r
263 errorThrown = true;
\r
265 Assert("re-add error not thrown",
\r
268 // TODO - hit NotSupportedException
\r
270 Hashtable h = new Hashtable();
\r
272 for (int i = 1; i <= max; i++) {
\r
274 AssertEquals("value wrong for " + i,
\r
281 public void TestClear() {
\r
282 // TODO - hit NotSupportedException
\r
283 Hashtable h = new Hashtable();
\r
284 AssertEquals("new table - count zero", 0, h.Count);
\r
286 for (int i = 1; i <= max; i++) {
\r
289 Assert("table don't gots stuff", h.Count > 0);
\r
291 AssertEquals("Table should be cleared",
\r
296 public class MyEqualityComparer : IEqualityComparer {
\r
297 public bool Equals (object x, object y) { return x == y; }
\r
298 public int GetHashCode (object obj) { return 1; }
\r
301 public class MyHashtable : Hashtable {
\r
302 public MyHashtable (IEqualityComparer c): base (c){}
\r
304 public IEqualityComparer GetComparer ()
\r
306 return EqualityComparer;
\r
313 public void TestClone() {
\r
315 char[] c1 = {'a', 'b', 'c'};
\r
316 char[] c2 = {'d', 'e', 'f'};
\r
317 Hashtable h1 = new Hashtable();
\r
318 for (int i = 0; i < c1.Length; i++) {
\r
321 Hashtable h2 = (Hashtable)h1.Clone();
\r
322 AssertNotNull("got no clone!", h2);
\r
323 AssertNotNull("clone's got nothing!", h2[c1[0]]);
\r
324 for (int i = 0; i < c1.Length; i++) {
\r
325 AssertEquals("Hashtable match",
\r
326 h1[c1[i]], h2[c1[i]]);
\r
330 char[] c1 = {'a', 'b', 'c'};
\r
331 char[] c20 = {'1', '2'};
\r
332 char[] c21 = {'3', '4'};
\r
333 char[] c22 = {'5', '6'};
\r
334 char[][] c2 = {c20, c21, c22};
\r
335 Hashtable h1 = new Hashtable();
\r
336 for (int i = 0; i < c1.Length; i++) {
\r
339 Hashtable h2 = (Hashtable)h1.Clone();
\r
340 AssertNotNull("got no clone!", h2);
\r
341 AssertNotNull("clone's got nothing!", h2[c1[0]]);
\r
342 for (int i = 0; i < c1.Length; i++) {
\r
343 AssertEquals("Hashtable match",
\r
344 h1[c1[i]], h2[c1[i]]);
\r
347 ((char[])h1[c1[0]])[0] = 'z';
\r
348 AssertEquals("shallow copy", h1[c1[0]], h2[c1[0]]);
\r
352 MyEqualityComparer a = new MyEqualityComparer ();
\r
353 MyHashtable mh1 = new MyHashtable (a);
\r
354 MyHashtable mh2 = (MyHashtable) h1.Clone ();
\r
356 AssertEquals ("EqualityComparer", mh1.GetComparer (), mh2.GetComparer ());
\r
362 public void TestContains() {
\r
364 bool errorThrown = false;
\r
366 Hashtable h = new Hashtable();
\r
367 bool result = h.Contains(null);
\r
368 } catch (ArgumentNullException e) {
\r
369 errorThrown = true;
\r
370 AssertEquals("ParamName is not 'key'", "key", e.ParamName);
\r
372 Assert("null add error not thrown",
\r
376 Hashtable h = new Hashtable();
\r
377 for (int i = 0; i < 10000; i += 2)
\r
381 for (int i = 0; i < 10000; i += 2)
\r
383 Assert("hashtable must contain"+i.ToString(), h.Contains(i));
\r
384 Assert("hashtable does not contain "+((int)(i+1)).ToString(), !h.Contains(i+1));
\r
390 public void TestContainsKey() {
\r
392 bool errorThrown = false;
\r
395 Hashtable h = new Hashtable();
\r
396 bool result = h.Contains(null);
\r
398 catch (ArgumentNullException e)
\r
400 errorThrown = true;
\r
401 AssertEquals("ParamName is not 'key'", "key", e.ParamName);
\r
403 Assert("null add error not thrown",
\r
407 Hashtable h = new Hashtable();
\r
408 for (int i = 0; i < 1000; i += 2)
\r
412 for (int i = 0; i < 1000; i += 2)
\r
414 Assert("hashtable must contain"+i.ToString(), h.Contains(i));
\r
415 Assert("hashtable does not contain "+((int)(i+1)).ToString(), !h.Contains(i+1));
\r
422 public void TestContainsValue() {
\r
424 Hashtable h = new Hashtable();
\r
426 Assert("blue? it's in there!",
\r
427 h.ContainsValue("blue"));
\r
428 Assert("green? no way!",
\r
429 !h.ContainsValue("green"));
\r
430 Assert("null? no way!",
\r
431 !h.ContainsValue(null));
\r
433 Assert("null? it's in there!",
\r
434 h.ContainsValue(null));
\r
440 public void TestCopyTo() {
\r
442 bool errorThrown = false;
\r
444 Hashtable h = new Hashtable();
\r
446 } catch (ArgumentNullException e) {
\r
447 errorThrown = true;
\r
448 AssertEquals("ParamName is not \"array\"", "array", e.ParamName);
\r
450 Assert("null hashtable error not thrown",
\r
454 bool errorThrown = false;
\r
456 Hashtable h = new Hashtable();
\r
457 Object[] o = new Object[1];
\r
459 } catch (ArgumentOutOfRangeException e) {
\r
460 errorThrown = true;
\r
461 AssertEquals("ParamName is not \"arrayIndex\"", "arrayIndex", e.ParamName);
\r
463 Assert("out of range error not thrown",
\r
467 bool errorThrown = false;
\r
469 Hashtable h = new Hashtable();
\r
470 Object[,] o = new Object[1,1];
\r
472 } catch (ArgumentException) {
\r
473 errorThrown = true;
\r
475 Assert("multi-dim array error not thrown",
\r
479 bool errorThrown = false;
\r
481 Hashtable h = new Hashtable();
\r
482 h['a'] = 1; // no error if table is empty
\r
483 Object[] o = new Object[5];
\r
485 } catch (ArgumentException) {
\r
486 errorThrown = true;
\r
488 Assert("no room in array error not thrown",
\r
492 bool errorThrown = false;
\r
494 Hashtable h = new Hashtable();
\r
498 Object[] o = new Object[2];
\r
500 } catch (ArgumentException) {
\r
501 errorThrown = true;
\r
503 Assert("table too big error not thrown",
\r
507 bool errorThrown = false;
\r
509 Hashtable h = new Hashtable();
\r
513 Char[] o = new Char[3];
\r
515 } catch (InvalidCastException) {
\r
516 errorThrown = true;
\r
518 Assert("invalid cast error not thrown",
\r
523 Hashtable h = new Hashtable();
\r
526 DictionaryEntry[] o = new DictionaryEntry[2];
\r
528 #if TARGET_JVM // Hashtable is not an ordered collection!
\r
529 if (o[0].Key.Equals('b')) {
\r
530 DictionaryEntry v = o[0];
\r
534 #endif // TARGET_JVM
\r
535 AssertEquals("first copy fine.", 'a', o[0].Key);
\r
536 AssertEquals("first copy fine.", 1, o[0].Value);
\r
537 AssertEquals("second copy fine.", 'b', o[1].Key);
\r
538 AssertEquals("second copy fine.", 2, o[1].Value);
\r
543 public void TestGetEnumerator() {
\r
544 String[] s1 = {"this", "is", "a", "test"};
\r
545 Char[] c1 = {'a', 'b', 'c', 'd'};
\r
546 Hashtable h1 = new Hashtable();
\r
547 for (int i = 0; i < s1.Length; i++) {
\r
550 IDictionaryEnumerator en = h1.GetEnumerator();
\r
551 AssertNotNull("No enumerator", en);
\r
553 for (int i = 0; i < s1.Length; i++) {
\r
555 Assert("Not enumerating for " + en.Key,
\r
556 Array.IndexOf(s1, en.Key) >= 0);
\r
557 Assert("Not enumerating for " + en.Value,
\r
558 Array.IndexOf(c1, en.Value) >= 0);
\r
563 public void TestSerialization () {
\r
564 Hashtable table1 = new Hashtable();
\r
566 Stream str = new MemoryStream ();
\r
567 BinaryFormatter formatter = new BinaryFormatter();
\r
569 for (int i = 0; i < 100; i++)
\r
570 table1[i] = "TestString Key: " + i.ToString();
\r
572 formatter.Serialize (str, table1);
\r
574 table2 = (Hashtable) formatter.Deserialize (str);
\r
577 foreach (DictionaryEntry de in table1)
\r
578 AssertEquals (de.Value, table2 [de.Key]);
\r
582 [Category ("TargetJvmNotWorking")]
\r
583 public void TestSerialization2 () {
\r
584 // Test from bug #70570
\r
585 MemoryStream stream = new MemoryStream();
\r
586 BinaryFormatter formatter = new BinaryFormatter();
\r
588 Hashtable table = new Hashtable();
\r
589 table.Add (new Bug(), "Hello");
\r
591 formatter.Serialize(stream, table);
\r
592 stream.Position = 0;
\r
593 table = (Hashtable) formatter.Deserialize(stream);
\r
594 AssertEquals ("#1", 1, table.Count);
\r
598 public void TestRemove() {
\r
600 bool errorThrown = false;
\r
602 Hashtable h = new Hashtable();
\r
604 } catch (ArgumentNullException e) {
\r
605 errorThrown = true;
\r
606 AssertEquals("ParamName is not \"key\"", "key", e.ParamName);
\r
608 Assert("null hashtable error not thrown",
\r
612 string[] keys = {"this", "is", "a", "test"};
\r
613 char[] values = {'a', 'b', 'c', 'd'};
\r
614 Hashtable h = new Hashtable();
\r
615 for (int i = 0; i < keys.Length; i++) {
\r
616 h[keys[i]] = values[i];
\r
618 AssertEquals("not enough in table",
\r
621 AssertEquals("not enough in table",
\r
624 AssertEquals("Wrong count in table",
\r
627 AssertEquals("Wrong count in table",
\r
633 public void TestSynchronized() {
\r
635 bool errorThrown = false;
\r
637 Hashtable h = Hashtable.Synchronized(null);
\r
638 } catch (ArgumentNullException e) {
\r
639 errorThrown = true;
\r
640 AssertEquals("ParamName is not \"table\"", "table", e.ParamName);
\r
642 Assert("null hashtable error not thrown",
\r
646 Hashtable h = new Hashtable();
\r
647 Assert("hashtable not synced by default",
\r
648 !h.IsSynchronized);
\r
649 Hashtable h2 = Hashtable.Synchronized(h);
\r
650 Assert("hashtable should by synced",
\r
651 h2.IsSynchronized);
\r
656 protected Hashtable ht;
\r
657 private static Random rnd;
\r
660 public void SetUp() {
\r
661 ht=new Hashtable();
\r
665 private void SetDefaultData() {
\r
667 ht.Add("k1","another");
\r
668 ht.Add("k2","yet");
\r
669 ht.Add("k3","hashtable");
\r
673 public void TestAddRemoveClear() {
\r
675 Assert(ht.Count==0);
\r
678 Assert(ht.Count==3);
\r
682 ht.Add("k2","cool");
\r
683 } catch (ArgumentException) {thrown=true;}
\r
684 Assert("Must throw ArgumentException!",thrown);
\r
687 Assert(ht.Count==3);
\r
688 Assert(ht["k2"].Equals("cool"));
\r
693 public void TestCopyTo2() {
\r
695 Object[] entries=new Object[ht.Count];
\r
696 ht.CopyTo(entries,0);
\r
697 Assert("Not an entry.",entries[0] is DictionaryEntry);
\r
701 public void CopyTo_Empty ()
\r
703 Hashtable ht = new Hashtable ();
\r
704 AssertEquals ("Count", 0, ht.Count);
\r
705 object[] array = new object [ht.Count];
\r
706 ht.CopyTo (array, 0);
\r
710 public void TestUnderHeavyLoad() {
\r
713 String[] cache=new String[max*2];
\r
716 for (int i=0;i<max;i++) {
\r
717 int id=rnd.Next()&0xFFFF;
\r
718 String key=""+id+"-key-"+id;
\r
719 String val="value-"+id;
\r
720 if (ht[key]==null) {
\r
728 Assert(ht.Count==n);
\r
730 for (int i=0;i<n;i++) {
\r
731 String key=cache[i];
\r
732 String val=ht[key] as String;
\r
733 String err="ht[\""+key+"\"]=\""+val+
\r
734 "\", expected \""+cache[i+max]+"\"";
\r
735 Assert(err,val!=null && val.Equals(cache[i+max]));
\r
741 for (int i=r1;i<r2;i++) {
\r
742 ht.Remove(cache[i]);
\r
746 for (int i=0;i<n;i++) {
\r
747 if (i>=r1 && i<r2) {
\r
748 Assert(ht[cache[i]]==null);
\r
750 String key=cache[i];
\r
751 String val=ht[key] as String;
\r
752 String err="ht[\""+key+"\"]=\""+val+
\r
753 "\", expected \""+cache[i+max]+"\"";
\r
754 Assert(err,val!=null && val.Equals(cache[i+max]));
\r
758 ICollection keys=ht.Keys;
\r
760 foreach (Object key in keys) {
\r
761 Assert((key as String) != null);
\r
764 Assert(nKeys==ht.Count);
\r
767 ICollection vals=ht.Values;
\r
769 foreach (Object val in vals) {
\r
770 Assert((val as String) != null);
\r
773 Assert(nVals==ht.Count);
\r
779 /// Test hashtable with CaseInsensitiveHashCodeProvider
\r
780 /// and CaseInsensitive comparer.
\r
783 public void TestCaseInsensitive ()
\r
785 // Not very meaningfull test, just to make
\r
786 // sure that hcp is set properly set.
\r
787 Hashtable ciHashtable = new Hashtable(11,1.0f,CaseInsensitiveHashCodeProvider.Default,CaseInsensitiveComparer.Default);
\r
788 ciHashtable ["key1"] = "value";
\r
789 ciHashtable ["key2"] = "VALUE";
\r
790 Assert(ciHashtable ["key1"].Equals ("value"));
\r
791 Assert(ciHashtable ["key2"].Equals ("VALUE"));
\r
793 ciHashtable ["KEY1"] = "new_value";
\r
794 Assert(ciHashtable ["key1"].Equals ("new_value"));
\r
799 public void TestCopyConstructor ()
\r
803 Hashtable htCopy = new Hashtable (ht);
\r
805 Assert(ht.Count == htCopy.Count);
\r
809 public void TestEnumerator ()
\r
813 IEnumerator e = ht.GetEnumerator ();
\r
815 while (e.MoveNext ()) {}
\r
817 Assert (!e.MoveNext ());
\r
822 [ExpectedException (typeof (ArgumentNullException))]
\r
823 public void GetObjectData_NullSerializationInfo ()
\r
826 ht.GetObjectData (null, new StreamingContext ());
\r
831 [Category ("NotDotNet")] // .NET raises InvalidOperationException.
\r
832 public void SyncHashtable_ICollectionsGetEnumerator ()
\r
834 Hashtable hashtable = Hashtable.Synchronized (new Hashtable ());
\r
835 hashtable["a"] = 1;
\r
836 //IEnumerator e = (hashtable.Clone() as
\r
837 IEnumerator e = (hashtable as ICollection).GetEnumerator ();
\r
840 DictionaryEntry de = (DictionaryEntry) e.Current;
\r
844 public void SerializableSubClasses ()
\r
846 Hashtable ht = new Hashtable ();
\r
848 Assert ("Keys.IsSerializable", ht.Keys.GetType ().IsSerializable);
\r
849 Assert ("Values.IsSerializable", ht.Values.GetType ().IsSerializable);
\r
850 Assert ("GetEnumerator.IsSerializable", ht.GetEnumerator ().GetType ().IsSerializable);
\r
851 Assert ("Synchronized.IsSerializable", Hashtable.Synchronized (ht).GetType ().IsSerializable);
\r
855 public void TestHashtableWithCustomComparer ()
\r
858 IDHashtable dd = new IDHashtable ();
\r
859 Random r = new Random (1000);
\r
860 for (int n = 0; n < 10000; n++) {
\r
861 int v = r.Next (0, 1000);
\r
863 v = r.Next (0, 1000);
\r
869 class IDHashtable : Hashtable {
\r
871 class IDComparer : IComparer {
\r
872 public int Compare (object x, object y)
\r
874 if ((int) x == (int) y)
\r
881 class IDHashCodeProvider : IHashCodeProvider {
\r
882 public int GetHashCode (object o)
\r
888 public IDHashtable ()
\r
889 : base (new IDHashCodeProvider (),
\r
896 public class Bug :ISerializable {
\r
899 private sealed class InnerClassSerializationHelper : IObjectReference {
\r
900 public object GetRealObject( StreamingContext context )
\r
906 void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context )
\r
908 info.SetType( typeof(InnerClassSerializationHelper) );
\r