M
Michi Henning
Looking at the documentation for System.Collections.CollectionBase
(http://msdn2.microsoft.com/en-us/library/
system.collections.collectionbase.aspx), I find:
public abstract class CollectionBase : IList, ICollection, IEnumerable
So, CollectionBase implements IList.
Looking at the IList members, we see:
int Add (Object value)
So, I can add anything to an IList.
Now I implement a type-safe collection of integers using
CollectionBase:
public class S : System.Collections.CollectionBase
{
public int Add(int i)
{
return InnerList.Add(i);
}
}
This now is type safe:
S s = new S();
s.Add("Hello"); // Compile-time error, as expected.
The compiler says:
The best overloaded method match for 'Example.S.Add(int)' has some
invalid arguments
Argument '1': cannot convert from 'string' to 'int'
Of course, that's what I want because the collection is supposed to
contain only integers, not strings.
However, I have several questions:
1) How is this actually implemented? That is, how does the
CollectionBase implementation prevent me from calling the Add(object o
value) method that is present on the IList interface? As far as I can
see, I cannot do this in C#. Or, to put it differently, I don't think
I could write CollectionBase myself in C#. Is that the correct view?
2) As far as I can see, the type system gets bent rather severely by
this. After all, CollectionBase says that it implements IList, and
IList promises that it provides its Add() method but, when I try to
call that Add() method, I get a compile-time error. Now, is the method
there or not? Does CollectionBase implement IList or not?
3) Consider the following code that uses the above class S:
static void addSomething(System.Collections.IList l)
{
l.Add("Hello");
}
So, addSomething() is a method that adds an element of type string to
the IList that is passed by the caller.
Now I write:
S s = new S(); // Type-safe collection of ints derived from
CollectionBase
addSomething(s);
System.Collections.IEnumerator e = s.GetEnumerator();
e.MoveNext();
System.Console.WriteLine(e.Current);
When I run this code, it prints:
Hello
In other words, I just have added added a string to my supposedly type-
safe collection of ints. All that was necessary was to pass the
instance as type IList to addSomething().
So, a CollectionBase is indeed an IList because I can pass it as an
IList and, if I do, I can invoke operations on IList, such as
Add(Object val). But, if I deal with my class S as type S and try to
call Add(Object val), I get a compile-time error. So, it appears that
a class derived from CollectionBase is somewhat schizophrenic?
Cheers,
Michi.
(http://msdn2.microsoft.com/en-us/library/
system.collections.collectionbase.aspx), I find:
public abstract class CollectionBase : IList, ICollection, IEnumerable
So, CollectionBase implements IList.
Looking at the IList members, we see:
int Add (Object value)
So, I can add anything to an IList.
Now I implement a type-safe collection of integers using
CollectionBase:
public class S : System.Collections.CollectionBase
{
public int Add(int i)
{
return InnerList.Add(i);
}
}
This now is type safe:
S s = new S();
s.Add("Hello"); // Compile-time error, as expected.
The compiler says:
The best overloaded method match for 'Example.S.Add(int)' has some
invalid arguments
Argument '1': cannot convert from 'string' to 'int'
Of course, that's what I want because the collection is supposed to
contain only integers, not strings.
However, I have several questions:
1) How is this actually implemented? That is, how does the
CollectionBase implementation prevent me from calling the Add(object o
value) method that is present on the IList interface? As far as I can
see, I cannot do this in C#. Or, to put it differently, I don't think
I could write CollectionBase myself in C#. Is that the correct view?
2) As far as I can see, the type system gets bent rather severely by
this. After all, CollectionBase says that it implements IList, and
IList promises that it provides its Add() method but, when I try to
call that Add() method, I get a compile-time error. Now, is the method
there or not? Does CollectionBase implement IList or not?
3) Consider the following code that uses the above class S:
static void addSomething(System.Collections.IList l)
{
l.Add("Hello");
}
So, addSomething() is a method that adds an element of type string to
the IList that is passed by the caller.
Now I write:
S s = new S(); // Type-safe collection of ints derived from
CollectionBase
addSomething(s);
System.Collections.IEnumerator e = s.GetEnumerator();
e.MoveNext();
System.Console.WriteLine(e.Current);
When I run this code, it prints:
Hello
In other words, I just have added added a string to my supposedly type-
safe collection of ints. All that was necessary was to pass the
instance as type IList to addSomething().
So, a CollectionBase is indeed an IList because I can pass it as an
IList and, if I do, I can invoke operations on IList, such as
Add(Object val). But, if I deal with my class S as type S and try to
call Add(Object val), I get a compile-time error. So, it appears that
a class derived from CollectionBase is somewhat schizophrenic?
Cheers,
Michi.