OOP/Design Question

  • Thread starter Thread starter codymanix
  • Start date Start date
C

codymanix

I have a class Customer. A customer can have multiple accounts. The
account-data is hold internally in a datatable but this implementation
detail should be hidden from the user of the class customer.

the user of the class customer should be able to use foreach on
customer.Accounts and can do a customer.Accounts.Count. indexing should not
be neccessary because the order is not important.

How can I accomplish this? I cannot use IList and its derivats because they
are not readonly also the readonly IList-wrapperclasses throw a exception if
somebody tries to modifiy them but I want to catch that with the compiler!

public class Customer
{
public <whatever> Accounts
{
get
{
return <whatever>
}
}
}

public class Account
{
}
 
Hallo Codymanix,
i'm not quite sure, wether i fully understand, what you want, but concerning
the iterating through all accounts you could do the following:
You could store all your account objects in the customer object in an
ArrayList (System.Collections). The ArrayList is a private field of the
customer class. To make your user iterate through all accounts, you have to
implement the IEnumerable interface for your customer class. It has just
one member GetEnumerator(), which returns an IEnumerator interface. Here you
can use the interface of the internal ArrayList field.

public class Customer : IEnumerable {
private ArrayList alAccounts = new ArrayList();
...
public IEnumerator GetEnumerator() {
return(alAccounts.GetEnumerator());
}

public int Count { get { return(alAccounts.Count); } }
...
}

Hope that helps
Reinhold
 
i'm not quite sure, wether i fully understand, what you want, but concerning
the iterating through all accounts you could do the following:
You could store all your account objects in the customer object in an
ArrayList (System.Collections). The ArrayList is a private field of the
customer class. To make your user iterate through all accounts, you have to
implement the IEnumerable interface for your customer class. It has just
one member GetEnumerator(), which returns an IEnumerator interface. Here you
can use the interface of the internal ArrayList field.

public class Customer : IEnumerable {
private ArrayList alAccounts = new ArrayList();
...
public IEnumerator GetEnumerator() {
return(alAccounts.GetEnumerator());
}

public int Count { get { return(alAccounts.Count); } }
...
}

Hope that helps
Reinhold


Thank you, but your proposed solution brings some problems with it:

- I have to double-manage the accounts: in the arraylist *and* in the
datatable
- I want to access the accounts like customer.Accounts because Customer
might hold more collections like discounts or orders.
 
Hallo cody,
the use of ArrayList was just to demonstrate a possible way.
As far as i understand now, you want to achieve the following:
- the customer class should expose some "collections" (for example the
accounts)
- the user of your customer class should be able to directly access these
colections (customerObj.Accounts) (?)
- the user of your customer class should be able to iterate through these
collections using foreach
- the user of your customer class should be able to get the number of
elements in these collections

So i would propose the following:
- You have to implement the element class (account) (or classes)
- You have to "implement" the collections (perhaps a wrapper around your
data-table)
- You have to implement IEnumerable for your customer class an IEnumerator
for your "collection". IEnumerator has three members: Reset(), MoveNext()
and a property named Current. Implementation is your turn. So ou can rely on
your data-table.
- You have to implement different properties in your customer class giving
the number of elements in the collection

Perhaps this could give some more usefull hints...
Reinhold
 
the use of ArrayList was just to demonstrate a possible way.
As far as i understand now, you want to achieve the following:
- the customer class should expose some "collections" (for example the
accounts)
- the user of your customer class should be able to directly access these
colections (customerObj.Accounts) (?)
- the user of your customer class should be able to iterate through these
collections using foreach
- the user of your customer class should be able to get the number of
elements in these collections

So i would propose the following:
- You have to implement the element class (account) (or classes)
- You have to "implement" the collections (perhaps a wrapper around your
data-table)
- You have to implement IEnumerable for your customer class an IEnumerator
for your "collection". IEnumerator has three members: Reset(), MoveNext()
and a property named Current. Implementation is your turn. So ou can rely on
your data-table.
- You have to implement different properties in your customer class giving
the number of elements in the collection

So I have additional to the Customer class implement the following classes:

Account
AccountCollection
AccountEnumerator

you can't be serious: for each new collection (orders,discounts) I have to
implement all 3 classes.
I was hoping there is a better (easier, simpler, more efficient) way..
 
codymanix said:
rely

So I have additional to the Customer class implement the following classes:

Account
AccountCollection
AccountEnumerator

Not really. You do not implement a complete Enumerator class. You just
implement the interface IEnumerator in your collection class (for example
AccountCollection). So you have two classes - element class and
coressponding collection of elements.
you can't be serious: for each new collection (orders,discounts) I have to

I think this *is* the "normal" way to go: if you want to have a collection
of elements, then you would at least have to implement the element class!
If you can't use one of the predefined collection classes of .NET (for
example ArrayList), then you have to implement your own collection.
I'm sorry - but that's the way to go!
 
So I have additional to the Customer class implement the following
classes:

Not really. You do not implement a complete Enumerator class. You just
implement the interface IEnumerator in your collection class (for example
AccountCollection). So you have two classes - element class and
coressponding collection of elements.
to

I think this *is* the "normal" way to go: if you want to have a collection
of elements, then you would at least have to implement the element class!
If you can't use one of the predefined collection classes of .NET (for
example ArrayList), then you have to implement your own collection.
I'm sorry - but that's the way to go!


OK, I see. I will use that for solving the problem. Thank you.

But sometimes it is strange how easiest things are extremely complicated in
C#.
in C++ I would simply do:

class Customer
{
const list<Account> GettAccounts()
{
return accountlist;
}
}

so I would have a constant list where the user can get the count and
enumerate over. I will never understand why C# provides no such
functionality.
At least a readonly wrapper-class for list could we expect! Throwing a "list
is readonly" exception at runtime is the worst thing that somebody could
imagine.
 
codymanix said:
have


OK, I see. I will use that for solving the problem. Thank you.

But sometimes it is strange how easiest things are extremely complicated in
C#.
in C++ I would simply do:

class Customer
{
const list<Account> GettAccounts()
{
return accountlist;
}
}

so I would have a constant list where the user can get the count and
enumerate over. I will never understand why C# provides no such
functionality.
At least a readonly wrapper-class for list could we expect! Throwing a "list
is readonly" exception at runtime is the worst thing that somebody could
imagine.

Yes you're right. Of course runtime exceptions are the worst thing!
What is really missing is indeed a read-only (or "const") collection. If
you want a read-only list, then you have to implement a wrapper.
But perhaps there is some light in the future... The next version of C#
(2.0) has at least generics (templates in C++). So you have a much more
stronger weapon to implement type-safe collections with one implementation.

Reinhold
 
You could use a class indexer

public class customer
{
private int[] AccountNo=new int(100);
public int this[int n
{
get
{
return AccountNo;
}
}
}


with regards,


J.V.Ravichandran
- http://www.geocities.com/
jvravichandran
- http://www.411asp.net/func/search?
qry=Ravichandran+J.V.&cob=aspnetpro
- http://www.southasianoutlook.com
- http://www.MSDNAA.Net
- http://www.csharphelp.com
- http://www.poetry.com/Publications/
display.asp?ID=P3966388&BN=999&PN=2
- Or, just search on "J.V.Ravichandran"
at http://www.Google.com
 
You could use a class indexer
public class customer
{
private int[] AccountNo=new int(100);
public int this[int n
{
get
{
return AccountNo;
}
}
}


This is not sufficient for me since the customer can not only hold Accounts,
it can have Discounts, Orders whatever.
Therefore I decided to solve the problem in the following way:

I implement Account, AccountCollection, Discount, DiscountCollection..Then I
make getter-Properties in the
Customer which returns an AccountCollection,Discountcollection. Although
this involves creating an additional
class for each property, it is imho good OOP style.
 
Back
Top