Type-Safe Collection of Diverse Types
So you have a couple of different objects (say, Foo and Bar), and would like to store them all in some sort of collection (Col), but in a type-safe way.
Here’s two solutions:
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4
5
6 // required only for Col2
7 public interface IItem {
8
9 void Print();
10
11 }
12
13
14 public class Foo : IItem {
15
16 public String Text;
17
18 public Foo(String text) {
19 Text = text;
20 Print();
21 }
22
23 public void Print() {
24 Console.Write("Foo:" + Text + "; ");
25 }
26
27 }
28
29
30 public class Bar : IItem {
31
32 public List<String> List;
33
34 public Bar(List<String> list) {
35 List = list;
36 Print();
37 }
38
39 public void Print() {
40 Console.Write("Bar:");
41 foreach (String item in List) {
42 Console.Write(item + ";");
43 }
44 Console.Write(" ");
45 }
46
47 }
48
49
50 // stores objects as they are, without casting
51 public class Col1 {
52
53 private List<Foo> fooList = new List<Foo>();
54
55 private List<Bar> barList = new List<Bar>();
56
57 private List<Char> order = new List<Char>();
58
59 public void Add(Foo item) {
60 fooList.Add(item);
61 order.Add('f');
62 }
63
64 public void Add(Bar item) {
65 barList.Add(item);
66 order.Add('b');
67 }
68
69 public void Print() {
70 var fooEnu = fooList.GetEnumerator();
71 var barEnu = barList.GetEnumerator();
72 foreach (Char list in order) {
73 switch (list) {
74 case 'f':
75 fooEnu.MoveNext();
76 fooEnu.Current.Print();
77 break;
78 case 'b':
79 barEnu.MoveNext();
80 barEnu.Current.Print();
81 break;
82 default:
83 throw new Exception();
84 }
85 }
86 }
87
88 }
89
90
91 // stores objects cast to interface
92 public class Col2 {
93
94 private List<IItem> list = new List<IItem>();
95
96 public void Add(IItem item) {
97 list.Add(item);
98 }
99
100 public void Print() {
101 foreach (IItem item in list) {
102 item.Print();
103 }
104 }
105
106 }
107
108
109 // test collection with random data
110 public class Test {
111
112 public static void Main() {
113 Col1 col = new Col1();
114 //Col2 col = new Col2();
115 Random rng = new Random();
116 for (Int16 i = 0; i < rng.Next(3, 10); i++) {
117 if (rng.Next(2) == 0) {
118 col.Add(new Foo(i.ToString()));
119 } else {
120 List<String> list = new List<String>();
121 for (Int16 i2 = 0; i2 < rng.Next(1, 4); i2++) {
122 list.Add(i.ToString() + i2.ToString());
123 }
124 col.Add(new Bar(list));
125 }
126 }
127 Console.WriteLine();
128 col.Print();
129 Console.WriteLine();
130 }
131
132 }
