layer:11

an addiction to or an obsession with acquiring, manipulating, and sharing information

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 }

2010-01-03 01:50

.NETMonoC Sharp

| Archive | RSS | E-mail | Twitter | Alvis Mikovs