By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,423 Members | 1,327 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,423 IT Pros & Developers. It's quick & easy.

System.Array and IList - language/framework design question

P: n/a
Hi

Straight to the point - I don't understand why System.Array derives
from IList (given the methods/properties actually on IList).

When designing an interface you specify a contract. Deriving from an
interface and only implementing some of it means something is wrong:
either the interface specification is wrong e.g. not minimal or the
derivation is wrong e.g. the type can't actually honour this contract.

Firstly, an array is fixed size so it doesn't make sense for it to
implement Add/Remove methods anyway (these appear on IList). So, they
throw exceptions but I don't think that Array should even need to be
implementing these in the first place!

Secondly, for an array, what does IList provide that System.Array
would not have otherwise? *Nothing* as far as I can see. So what's it
there for?

Thirdly, I think the actual current implementation is half-baked
anyway. For instance, get an IList from an Array with some objects and
call Clear. Then call Count. Then notice that Count isn't 0 - it
hasn't been synched by Clear. I realise that the specification of
Clear doesn't require this (see the docs) but still, you'd expect it
here.

Fourthly, I think the IList property IsFixedSize is strange. If a data
structure is fixed size it shouldn't have to implement Add/Remove
methods because it doesn't make sense. So there should be two separate
interfaces for fixed size data structures and for variable size data
structures.

These are just my ideas using really basic design guidelines. I'm
probably missing something or not seeing the full picture so some help
in this direction would be useful!

Thanks

Emma Middlebrook
em**************@fastmail.fm
Nov 15 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
You should've started with the 4th item because an answer to it would kind
of eliminate #1. The fact that they made one interface instead of two - I'd
say it's just a matter of taste. I kind of like having one, - less hassle
when you need to find out if the collection is readonly - no need to query
another interface. Besides, IList has a good description, as documentation
states - "Represents a collection of objects that can be individually
accessed by index.". I think the design does not contradict the description.

I don't quite understand what's that confusing about #2? The fact that Array
is implementing IList is just a matter of followind the pattern - all
collection classes in .NET implement either/some/all of these: IEnumerable,
ICollection, IList. And some pieces of functionality are based on using the
interfaces. For instance you can bind Array or ArrayList to a grid because
they both expose IList...

As far as #3 goes - well contains the answer, doesn't it? The docs say:
"Implementations of this method can vary in how they handle the
ICollection.Count and the capacity of a collection. Typically, the count is
set to zero. The capacity can be set to zero or a default value, or it can
remain unchanged." Hmmm.... In this particular implementation, calling Clear
doesn't change Count.... but that's documented, right? :)

Sincerely,
Val.

"emma middlebrook" <em**************@fastmail.fm> wrote in message
news:e2**************************@posting.google.c om...
Hi

Straight to the point - I don't understand why System.Array derives
from IList (given the methods/properties actually on IList).

When designing an interface you specify a contract. Deriving from an
interface and only implementing some of it means something is wrong:
either the interface specification is wrong e.g. not minimal or the
derivation is wrong e.g. the type can't actually honour this contract.

Firstly, an array is fixed size so it doesn't make sense for it to
implement Add/Remove methods anyway (these appear on IList). So, they
throw exceptions but I don't think that Array should even need to be
implementing these in the first place!

Secondly, for an array, what does IList provide that System.Array
would not have otherwise? *Nothing* as far as I can see. So what's it
there for?

Thirdly, I think the actual current implementation is half-baked
anyway. For instance, get an IList from an Array with some objects and
call Clear. Then call Count. Then notice that Count isn't 0 - it
hasn't been synched by Clear. I realise that the specification of
Clear doesn't require this (see the docs) but still, you'd expect it
here.

Fourthly, I think the IList property IsFixedSize is strange. If a data
structure is fixed size it shouldn't have to implement Add/Remove
methods because it doesn't make sense. So there should be two separate
interfaces for fixed size data structures and for variable size data
structures.

These are just my ideas using really basic design guidelines. I'm
probably missing something or not seeing the full picture so some help
in this direction would be useful!

Thanks

Emma Middlebrook
em**************@fastmail.fm

Nov 15 '05 #2

P: n/a
From what you're saying, Val, I don't see how you could criticize an
interface like this one:

public interface IBoxer {
bool IsCerealBoxer {get;}
bool IsAthleticBoxer {get;}
bool IsCanineBoxer {get;}

void FillCerealInBox();
void MoveAssemblyLine();
void Yawn();

void RightPunch();
void LeftJab();
void BiteEar();

void Bark();
void PlayDead();
void Shake();
}

My point is that things that are different should be in different
interfaces. Read only arrays and variable size arrays have many things in
common. So do cereal boxers with athletic boxers. (Both are human, both have
jobs, etc.) But they don't have enough in common to warrant putting them in
the same interface.

I'm with ya, emma.

Chris

"Val Savvateev" <ov*********@meridium.com_NO_SPAM> wrote in message
news:#u**************@TK2MSFTNGP09.phx.gbl...

"emma middlebrook" <em**************@fastmail.fm> wrote in message
news:e2**************************@posting.google.c om...
"Val Savvateev" <vs********@meridium.com_NO_SPAM> wrote in message news:<uM**************@TK2MSFTNGP10.phx.gbl>...
You should've started with the 4th item because an answer to it would kind of eliminate #1. The fact that they made one interface instead of two - I'd
say it's just a matter of taste. I kind of like having one, - less hassle when you need to find out if the collection is readonly - no need to query another interface. Besides, IList has a good description, as documentation states - "Represents a collection of objects that can be individually
accessed by index.". I think the design does not contradict the description.

I don't believe it's a matter of taste - an interface has an implicit
contract. You can't argue that because the documentation says it can
be used to access by index then it's OK. IList has semantics suitable
for data structures whose size can vary.
Not quite correct... Let's put it this way - IList sematics show that it

can be applied to structures of variable _or_ fixed size (depending on the value of IsFixedSize property). The structures could also be readonly (you can or cannot update particular elements based on the value of IsReadOnly
property). I think you underestimate the presense of the mentioned
properties. Also, isn't it logical after all that if you can update
particular elements using an interface then you also should be able to
add/remove the elements through the same interface....
If this interface was aimed
at fixed size
It was not. That's the point.
data structures then it's clearly wrong because fixed
size data structures cannot be expected to implement some of its
members e.g. Add/Remove!!


See value of IsFixedSize. I dont see any problem with that.
So, anyway, the IList itself is fine. It's
just not appropriate to derive an Array from it.


Hmm... "just not apporpriate" is not quite an argument... Why not
appropriate?
Some of the
functionality you say you like should be factored out as it's
orthogonal functionality to a list and maybe common to all data
structures. Then there'd be nothing wrong with Array and other
collections deriving from that new interface.


Well... I see your point, and it would be valid if the interface was

missing the two properties. I still think it was just matter of taste and let me
illustrate why. If the design was your way it would contain two interfaces
(or more) instead of single IList, something like this (pseudo-code):

IList
{
obect Item(index) {set;get;}
int IdexOf(item)
bool Contains(item)
bool IsReadOnly
}

IListManager
{
Add()
Insert()
Remove()
Clear()
....etc
}

Now imagine, I'm implementing my own datagrid. The grid should be editable
and allow for deleting and adding items based on whether the list is
fixedsize.
My initialization code for both designes would be different... but just
alittle........

In case of the proposed design:
Init(object source)
{
IList _items = source as IList;
IListManage _manager = source as IListManager;
bool _isFixedSize = (_manager != null);
}

In case of the current design I would not need to query for the manager
interface and I would just use properties on IList:

Init(object source)
{
IList _items = source as IList;
}
Datagrid would also be a good argument for having everything in one
interface - when you see list of items on the screen it's either editable or not (IsReadOnly) and you either can add/remove items or not
(IsFixedSize)..... "Manageability" of the list does not disprove the fact
that it's just a list....
I don't quite understand what's that confusing about #2? The fact that Array is implementing IList is just a matter of followind the pattern - all
collection classes in .NET implement either/some/all of these: IEnumerable, ICollection, IList. And some pieces of functionality are based on
using
the interfaces. For instance you can bind Array or ArrayList to a grid because they both expose IList...
I'm not confused, it just seems wrong. What is your pattern - you just
say some collections implement some interfaces?


Yep.... Ultimately all the collections in the library implement

IEnumerable (ICollection iherits IEnumerable, IList iherits ICollection) :

http://msdn.microsoft.com/library/en...collectionsien
umerableclasstopic.asp?frame=true
Binding ... would
explain a little further for my own education how this works and the
importance of IList in this - that would be appreciated as I don't
know much about binding.

http://msdn.microsoft.com/library/en...windowsformsda
tagridclassdatasourcetopic.asp?frame=true
IList is the simplest structure that can be used in binding...
As far as #3 goes - well contains the answer, doesn't it? The docs
say: "Implementations of this method can vary in how they handle the
ICollection.Count and the capacity of a collection. Typically, the count
is set to zero. The capacity can be set to zero or a default value, or it can remain unchanged." Hmmm.... In this particular implementation, calling Clear doesn't change Count.... but that's documented, right? :)
Yes, I know but I still think that's bad, documented or not!


Well, you see, I told ya! - just a matter of taste ("i know, but...") ...

:)
List the discussion....

Val

Cheers for your comments and discussion - I'm just saying really that
the IList interface should be factored out so Array can derive from
nicely defined interfaces each of which asks it to implement methods
that it can actually do!

Emma Middlebrook
em**************@fastmail.fm
Sincerely,
Val.

"emma middlebrook" <em**************@fastmail.fm> wrote in message
news:e2**************************@posting.google.c om...
> Hi
>
> Straight to the point - I don't understand why System.Array derives
> from IList (given the methods/properties actually on IList).
>
> When designing an interface you specify a contract. Deriving from an
> interface and only implementing some of it means something is wrong:
> either the interface specification is wrong e.g. not minimal or the
> derivation is wrong e.g. the type can't actually honour this

contract. >
> Firstly, an array is fixed size so it doesn't make sense for it to
> implement Add/Remove methods anyway (these appear on IList). So, they > throw exceptions but I don't think that Array should even need to be
> implementing these in the first place!
>
> Secondly, for an array, what does IList provide that System.Array
> would not have otherwise? *Nothing* as far as I can see. So what's it > there for?
>
> Thirdly, I think the actual current implementation is half-baked
> anyway. For instance, get an IList from an Array with some objects and > call Clear. Then call Count. Then notice that Count isn't 0 - it
> hasn't been synched by Clear. I realise that the specification of
> Clear doesn't require this (see the docs) but still, you'd expect it
> here.
>
> Fourthly, I think the IList property IsFixedSize is strange. If a data > structure is fixed size it shouldn't have to implement Add/Remove
> methods because it doesn't make sense. So there should be two separate > interfaces for fixed size data structures and for variable size data
> structures.
>
> These are just my ideas using really basic design guidelines. I'm
> probably missing something or not seeing the full picture so some help > in this direction would be useful!
>
> Thanks
>
> Emma Middlebrook
> em**************@fastmail.fm


Nov 15 '05 #3

P: n/a
I see your sarcazm, but I don't think your example is good enough, Chris.
You mention commonalities in your comments only. They're not expressed in
the desing at all. It is pretty normal that a list can be expanded or be of
a fixed size. It is also possible that a list can change behaviour with
time - become readonly for instance. On the other hand I don't think that
its pretty commong for a cereal boxer to bite ears off on the ring, or for
a doggy to end up yawning at an assembly line.

Well, here is an extreme of "correct" design that you guys will probably
like:

public interface IAthleticBoxer
{
void RightPunch();
}

public interface ICoolAthleticBoxer : IAthleticBoxer
{
void LeftJab();
}

public interface IMTysonKindOfBoxer : ICoolAthleticBoxer
{
void BiteEar();
}
Do you think there's something wrong with it (a hint - there is)?

Val.

"Chris Capel" <ch***@nowhere.com> wrote in message
news:%2******************@TK2MSFTNGP10.phx.gbl...
From what you're saying, Val, I don't see how you could criticize an
interface like this one:

public interface IBoxer {
bool IsCerealBoxer {get;}
bool IsAthleticBoxer {get;}
bool IsCanineBoxer {get;}

void FillCerealInBox();
void MoveAssemblyLine();
void Yawn();

void RightPunch();
void LeftJab();
void BiteEar();

void Bark();
void PlayDead();
void Shake();
}

My point is that things that are different should be in different
interfaces. Read only arrays and variable size arrays have many things in
common. So do cereal boxers with athletic boxers. (Both are human, both have jobs, etc.) But they don't have enough in common to warrant putting them in the same interface.

I'm with ya, emma.

Chris

"Val Savvateev" <ov*********@meridium.com_NO_SPAM> wrote in message
news:#u**************@TK2MSFTNGP09.phx.gbl...

"emma middlebrook" <em**************@fastmail.fm> wrote in message
news:e2**************************@posting.google.c om...
"Val Savvateev" <vs********@meridium.com_NO_SPAM> wrote in message news:<uM**************@TK2MSFTNGP10.phx.gbl>...
> You should've started with the 4th item because an answer to it would
kind
> of eliminate #1. The fact that they made one interface instead of two -
I'd
> say it's just a matter of taste. I kind of like having one, - less

hassle
> when you need to find out if the collection is readonly - no need to

query
> another interface. Besides, IList has a good description, as

documentation
> states - "Represents a collection of objects that can be
individually > accessed by index.". I think the design does not contradict the

description.

I don't believe it's a matter of taste - an interface has an implicit
contract. You can't argue that because the documentation says it can
be used to access by index then it's OK. IList has semantics suitable
for data structures whose size can vary.


Not quite correct... Let's put it this way - IList sematics show that it

can
be applied to structures of variable _or_ fixed size (depending on the

value
of IsFixedSize property). The structures could also be readonly (you can

or
cannot update particular elements based on the value of IsReadOnly
property). I think you underestimate the presense of the mentioned
properties. Also, isn't it logical after all that if you can update
particular elements using an interface then you also should be able to
add/remove the elements through the same interface....
If this interface was aimed
at fixed size


It was not. That's the point.
data structures then it's clearly wrong because fixed
size data structures cannot be expected to implement some of its
members e.g. Add/Remove!!


See value of IsFixedSize. I dont see any problem with that.
So, anyway, the IList itself is fine. It's
just not appropriate to derive an Array from it.


Hmm... "just not apporpriate" is not quite an argument... Why not
appropriate?
Some of the
functionality you say you like should be factored out as it's
orthogonal functionality to a list and maybe common to all data
structures. Then there'd be nothing wrong with Array and other
collections deriving from that new interface.


Well... I see your point, and it would be valid if the interface was

missing
the two properties. I still think it was just matter of taste and let me
illustrate why. If the design was your way it would contain two

interfaces (or more) instead of single IList, something like this (pseudo-code):

IList
{
obect Item(index) {set;get;}
int IdexOf(item)
bool Contains(item)
bool IsReadOnly
}

IListManager
{
Add()
Insert()
Remove()
Clear()
....etc
}

Now imagine, I'm implementing my own datagrid. The grid should be editable and allow for deleting and adding items based on whether the list is
fixedsize.
My initialization code for both designes would be different... but just
alittle........

In case of the proposed design:
Init(object source)
{
IList _items = source as IList;
IListManage _manager = source as IListManager;
bool _isFixedSize = (_manager != null);
}

In case of the current design I would not need to query for the manager
interface and I would just use properties on IList:

Init(object source)
{
IList _items = source as IList;
}
Datagrid would also be a good argument for having everything in one
interface - when you see list of items on the screen it's either editable or
not (IsReadOnly) and you either can add/remove items or not
(IsFixedSize)..... "Manageability" of the list does not disprove the
fact that it's just a list....
> I don't quite understand what's that confusing about #2? The fact that
Array
> is implementing IList is just a matter of followind the pattern -
all > collection classes in .NET implement either/some/all of these:

IEnumerable,
> ICollection, IList. And some pieces of functionality are based on

using
the
> interfaces. For instance you can bind Array or ArrayList to a grid

because
> they both expose IList...

I'm not confused, it just seems wrong. What is your pattern - you just
say some collections implement some interfaces?


Yep.... Ultimately all the collections in the library implement

IEnumerable
(ICollection iherits IEnumerable, IList iherits ICollection) :

http://msdn.microsoft.com/library/en...collectionsien umerableclasstopic.asp?frame=true
Binding ... would
explain a little further for my own education how this works and the
importance of IList in this - that would be appreciated as I don't
know much about binding.

http://msdn.microsoft.com/library/en...windowsformsda tagridclassdatasourcetopic.asp?frame=true

IList is the simplest structure that can be used in binding...
> As far as #3 goes - well contains the answer, doesn't it? The docs
say: > "Implementations of this method can vary in how they handle the
> ICollection.Count and the capacity of a collection. Typically, the count
is
> set to zero. The capacity can be set to zero or a default value, or it can
> remain unchanged." Hmmm.... In this particular implementation,
calling Clear
> doesn't change Count.... but that's documented, right? :)

Yes, I know but I still think that's bad, documented or not!


Well, you see, I told ya! - just a matter of taste ("i know, but...")

.... :)

List the discussion....

Val

Cheers for your comments and discussion - I'm just saying really that
the IList interface should be factored out so Array can derive from
nicely defined interfaces each of which asks it to implement methods
that it can actually do!

Emma Middlebrook
em**************@fastmail.fm

> Sincerely,
> Val.
>
> "emma middlebrook" <em**************@fastmail.fm> wrote in message
> news:e2**************************@posting.google.c om...
> > Hi
> >
> > Straight to the point - I don't understand why System.Array

derives > > from IList (given the methods/properties actually on IList).
> >
> > When designing an interface you specify a contract. Deriving from an > > interface and only implementing some of it means something is wrong: > > either the interface specification is wrong e.g. not minimal or the > > derivation is wrong e.g. the type can't actually honour this

contract. > >
> > Firstly, an array is fixed size so it doesn't make sense for it to
> > implement Add/Remove methods anyway (these appear on IList). So, they > > throw exceptions but I don't think that Array should even need to be > > implementing these in the first place!
> >
> > Secondly, for an array, what does IList provide that System.Array
> > would not have otherwise? *Nothing* as far as I can see. So what's it > > there for?
> >
> > Thirdly, I think the actual current implementation is half-baked
> > anyway. For instance, get an IList from an Array with some objects and > > call Clear. Then call Count. Then notice that Count isn't 0 - it
> > hasn't been synched by Clear. I realise that the specification of
> > Clear doesn't require this (see the docs) but still, you'd expect it > > here.
> >
> > Fourthly, I think the IList property IsFixedSize is strange. If a data > > structure is fixed size it shouldn't have to implement Add/Remove
> > methods because it doesn't make sense. So there should be two separate > > interfaces for fixed size data structures and for variable size data > > structures.
> >
> > These are just my ideas using really basic design guidelines. I'm
> > probably missing something or not seeing the full picture so some help > > in this direction would be useful!
> >
> > Thanks
> >
> > Emma Middlebrook
> > em**************@fastmail.fm



Nov 15 '05 #4

P: n/a
yes, you're right. the current .NET collection structure is very stupid.

much better would be following structure:

interface IReadOnlyList
{
Prev();
Next();
Count();
}

interface IReadOnlyArray : IReadOnlyList
{
GetAt(); // indexer
}

interface IArray : IReadOnlyArray
{
SetAt(); // indexer
}

interface IList : IReadOnlyList
{
Add();
Remove();
Insert();
Clear();
}

interface IArrayList : IArray, IList
{
}

this is imho the perfect solution. there is an interface for every need
and it is still kept simple. and dont't understand why microsoft solved
it in such a stupid manner.
*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Nov 15 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.