Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Collection of generic types

Tags:

c#

.net

generics

If I have a generic class:

public class MyClass<T>  {   public T Value; } 

I want to instantiate several items such as...

new MyClass<string> new MyClass<int> 

...and add them to a collection. How do I define the collection so that it can hold a list of generic types? I then want to iterate through the collection at some point, and use the Value property. Possible?

like image 364
Jeremy Avatar asked Jul 09 '10 18:07

Jeremy


People also ask

How are generics used in collections?

The generic collections disable the type-casting and there is no use of type-casting when it is used in generics. The generic collections are type-safe and checked at compile-time. These generic collections allow the datatypes to pass as parameters to classes.

What are generic collections?

A generic collection is strongly typed (you can store one type of objects into it) so that we can eliminate runtime type mismatches, it improves the performance by avoiding boxing and unboxing.

Are generic collections type safe?

Generic classes are used to provide the type safe structure -- type safe means only one type of data can be contained within Generic classes. The data type is defined at the time of an object initialization. We can have a different type of collection.


2 Answers

Have your generic class inherit from a non-generic base, or implement a non-generic interface. Then you can have a collection of this type and cast within whatever code you use to access the collection's contents.

Here's an example.

public abstract class MyClass {     public abstract Type Type { get; } }  public class MyClass<T> : MyClass {     public override Type Type     {         get { return typeof(T); }     }      public T Value { get; set; } }  // VERY basic illustration of how you might construct a collection // of MyClass<T> objects. public class MyClassCollection {     private Dictionary<Type, MyClass> _dictionary;      public MyClassCollection()     {         _dictionary = new Dictionary<Type, MyClass>();     }      public void Put<T>(MyClass<T> item)     {         _dictionary[typeof(T)] = item;     }      public MyClass<T> Get<T>()     {         return _dictionary[typeof(T)] as MyClass<T>;     } } 
like image 119
Dan Tao Avatar answered Sep 23 '22 02:09

Dan Tao


The only way I can think of, off the top of my head is as follows (wrapped up in a Console app for testing):

class Program {     static void Main(string[] args)     {         var x = new MyClass<string>() { Value = "34" };         var y = new MyClass<int>() { Value = 3 };          var list = new List<IMyClass>();         list.Add(x);         list.Add(y);          foreach (var item in list)         {             Console.WriteLine(item.GetValue);         }     }      private interface IMyClass     {         object GetValue { get; }     }      private class MyClass<T> : IMyClass     {         public T Value;          public object GetValue         {             get             {                return Value;             }         }     } } 

i.e. Have MyClass implement an empty interface and then create your collections as one that holds instances of classes that implement that interface.

Update: I've added a "GetValue" method to the interface that allows you to access the "Value" of the MyClass instance as an Object. This is about as good as it's going to get, afaik, if you want to have a collection that holds mixed types.

like image 28
Rob Avatar answered Sep 23 '22 02:09

Rob