IEnumerable versus implicit conversion

icon3
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...
Posted October 4, 2007 at 20:02 (UTC)

Maybe it's really just a sick thought, but who cares?! What is actually going to happen if one is enumerating an object which implements both an enumerator-interface and an implicit conversion to a type also implementing an enumerator-interface? At this time I actually know the answer (for Mono at least), but if we should reason about it, it's almost given that it should use the direct implementation of the enumarator-interface and in that way avoid an implicit conversion.

Now it's time to shower this post with some code (inspired by [1]):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
using System;
using System.Collections;
using System.Collections.Generic;
 
namespace experiments
{
	class MainClass
	{
		public static void Main(string[] args)
		{
			C<int> c = new C<int>(1, 2, 3, 4, 5);
 
			Console.WriteLine("IEnumerable<T>:");
			foreach (int e in c)
			{				
				Console.WriteLine(e);
			}
			Console.WriteLine();
 
			Console.WriteLine("Implicit conversion to List<T>:");			
			foreach (int e in (List<int>)c)
			{
				Console.WriteLine(e);
			}
			Console.WriteLine();
 
			Console.WriteLine("Implicit conversion to T[]:");
			foreach (int e in (int[])c)
			{
				Console.WriteLine(e);
			}
		}
	}	
 
	class C<T> : IEnumerable<T> 		
	{		
		protected List<T> list;
 
		public C(params T[] elements)
		{		
			this.list = new List<T>();
 
			for (int i = 0; i < elements.Length; ++i)
			{
				this.list.Add(elements[i]);
			}
		}
 
		public IEnumerator<T> GetEnumerator() 
		{
			for (int i = this.list.Count - 1; i >= 0; --i)
			{
				yield return this.list[i];
			}
		}
 
		IEnumerator IEnumerable.GetEnumerator() 
		{
			return GetEnumerator();
		}
 
		public static implicit operator List<T>(C<T> c)
		{
			return new List<T>(c.list);
		}		
 
		public static implicit operator T[](C<T> c)
		{
			T[] arr = new T[c.list.Count];			
 
			if (c.list.Count > 0)
			{
				int j = 0;
 
				for (int i = c.list.Count / 2; i >= 0; --i)
				{
					arr[j++] = c.list[i];
				}
 
				for (int i = (c.list.Count / 2) + 1; i < c.list.Count; ++i)
				{
					arr[j++] = c.list[i];
				}
			}
 
			return arr;
		}		
	}
}

And the result:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
IEnumerable<T>:
5
4
3
2
1
 
Implicit conversion to List<T>:
1
2
3
4
5
 
Implicit conversion to T[]:
3
2
1
4
5

..gets as expected - still a interesting test (in my opinion), though.

[1]: "C# Precisely" by Peter Sestoft and Henrik I. Hansen

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.