I'm relatively new to C# and polymorphism, so what I'm trying to accomplish
may not be possible, or there may be a totally different approach that I
should be taking.
I have a base class (MyBase) and a collection of MyBase objects
(MyBaseCollecti on). Now, I also have an extension to MyBase (MyExtendedBase
: MyBase) that has additional properties. And lastly, I have a collection
of MyExtendedBase objects(MyExten dedBaseCollecti on : MyBaseCollectio n).
I have a data layer that has a method (GetMyBaseColle ction) that retrieves
records from the database, and populates a MyBaseCollectio n with these
records. However, there are cases where I need to use this method to
populate a MyExtendedBaseC ollection. But here's the catch -- I want my data
layer to be unaware (and independent) of MyExtendedBase and
MyExtendedBaseC ollection.
I have tried several different ways to accomplish this, but no matter what I
do, I end up needing to up-cast MyBase to MyExtendedBase, which is illegal
in C#. I need my data layer to be able to accept and populate a
MyBaseCollectio n (with it possibly being a sub class of a
MyExtendedBaseC ollection) with MyBase objects (with them possibly being sub
classes of MyExtendedBase) , and then when the collection is returned, the
items in the collection are of the appropriate type (depending on the type
of collection passed in).
I have read about different design patterns (namely Decorator and
Composite), but am not sure if they apply to my situation, and if so, how to
implement them accordingly.
Again, I may be doing something totally illogical, so I'm open to any
suggestions you may have. Also, if I have not provided enough info, let me
know and I will follow up.
Thanks in advance.
Jerad 14 2581
I think your're pretty close. If you have a base class, then you should
have no problem passing MyExtendedBaseC ollection as a MyBaseCollectio n
object. This is the power of polymorphism.
A couple of your statements: need my data layer to be able to accept and populate a MyBaseCollectio n (with it possibly being a sub class of a MyExtendedBaseC ollection) with MyBase objects (with them possibly being sub classes of MyExtendedBase) ,
MyExtendedBase and MyExtendedBaseC ollection are sub classes of MyBase
and MyBaseCollectio n.
When you say a "subclass" it means that it inherits from a base class
or abstract class. I think you have the terminology backwards.
If you are trying to cast MyBase to MyExtendedBase, this is not going
to work. When you need to pass around a specialized type of class, but
dont want to code additional methods (apart from special functionality)
then you cast your dervied or subclasses (MyExtendedBase ) to type
MyBase, you can then pass it around as normal, any methods that are in
the base class that you override in the subclass, can be called as
normal because both the base class and sub class have definitions for
those methods.
Another way to accomplish this would be to use interfaces.
As far as the design patterns, this is something I am still learning as
well, I have found that if you dont understand the design pattern
completely, then dont use it at all. because chances are is that you
will miuse the pattern, and create more headaches then solutions.
hope my comments help!
Jerad Rose wrote: do, I end up needing to up-cast MyBase to MyExtendedBase, which is illegal
That's a down-cast. It's "legal" (staticly valid), but if the actual
object instance casted is not an instance of MyExtendedBase the cast
will fail and throw an exception.
Again, I may be doing something totally illogical, so I'm open to any suggestions you may have. Also, if I have not provided enough info, let me know and I will follow up.
Let the data-layer, that should be generic in the types, accept the
data-structure to fill items into as an argument. If your data layer
needs to construct "unknown" type objects from data you can have a look
at the factory-pattern. The data-layer can accept, as a parameter, a
factory that is given the data to parse and create an object from that.
BTW: Are you in C#1 or 2?
Decorator and composite are completely unrelated to your problem.
--
Helge Jensen
mailto:he****** ****@slog.dk
sip:he********* *@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Hi Jerad,
You only need one collection. The one for the base class.
When you're pulling in data from the database test the attribute(s) that
mark the difference between Mybase and MyExtendedBase before instantiating
the object that you are going to add to the collection.
bool MyDatabaseGetRo utine(ref collection col)
{
SQlDataCommand etc setup.
MyBase b;
While MyDatareader.re ad
{
If(MyDataReader .GetString(say5 ) == dbNull) //Instantiate a MyBase
b=new MyBase();
else // Instantiate a MyBaseExtended
b= new MyBaseExtended( );
// Now fill the common (MyBase) properties
b.Common1 = MyDataRead.GetS tring(0);
b.Common2 = MyDataRead.GetS tring(1);
Test again for type.
if (b.GetType().To String()=="MyBa seExtended")
{
// Fill the extended properties
}
col.add(b); Adding to collection regardless of Instantiation.
When you come to use the collection iterate across it with a base type
variable
bool LetsUnpackIt(co llection col)
foreach (mybase b in col)
{
if (b.gettype().To String()=="MyBa se")
//Do the mybase things
else
// Do the myBaseExtended things
HTH
Bob
"Jerad Rose" <no@spam.com> wrote in message
news:ea******** ******@TK2MSFTN GP09.phx.gbl... I'm relatively new to C# and polymorphism, so what I'm trying to
accomplish may not be possible, or there may be a totally different approach that I should be taking.
I have a base class (MyBase) and a collection of MyBase objects (MyBaseCollecti on). Now, I also have an extension to MyBase
(MyExtendedBase : MyBase) that has additional properties. And lastly, I have a collection of MyExtendedBase objects(MyExten dedBaseCollecti on : MyBaseCollectio n).
I have a data layer that has a method (GetMyBaseColle ction) that retrieves records from the database, and populates a MyBaseCollectio n with these records. However, there are cases where I need to use this method to populate a MyExtendedBaseC ollection. But here's the catch -- I want my
data layer to be unaware (and independent) of MyExtendedBase and MyExtendedBaseC ollection.
I have tried several different ways to accomplish this, but no matter what
I do, I end up needing to up-cast MyBase to MyExtendedBase, which is illegal in C#. I need my data layer to be able to accept and populate a MyBaseCollectio n (with it possibly being a sub class of a MyExtendedBaseC ollection) with MyBase objects (with them possibly being
sub classes of MyExtendedBase) , and then when the collection is returned, the items in the collection are of the appropriate type (depending on the type of collection passed in).
I have read about different design patterns (namely Decorator and Composite), but am not sure if they apply to my situation, and if so, how
to implement them accordingly.
Again, I may be doing something totally illogical, so I'm open to any suggestions you may have. Also, if I have not provided enough info, let
me know and I will follow up.
Thanks in advance.
Jerad
Thanks for the responses, guys.
To clarify on a few comments:
dkode wrote: When you say a "subclass" it means that it inherits
from a base class or abstract class. I think you have
the terminology backwards.
Yeah, I guess I was thinking the "subclass" would be the more generic one
and have fewer members, sort of like a subset. Thanks for the
clarification.
dkode wrote:
I have found that if you dont understand the design
pattern completely, then dont use it at all.
I tend to agree with you there, which was why I wouldn't have used them
unless somebody could have helped me understand them.
Helge Jensen wrote:
That's a down-cast. It's "legal" (staticly valid), but
if the actual object instance casted is not an instance
of MyExtendedBase the cast will fail and throw an
exception.
Yeah, that's what I meant (see example below). But I did get the
up-/down-cast confused. But I think I've seen other people posting this
backwards as well.
Helge Jensen wrote:
The data-layer can accept, as a parameter, a factory that is given the data to parse and create
an object from that.
It seems this is the recommended way to go. And I had thought about going
this route originally, but the thing I don't like about using a factory is
that my data layer is dependent on this factory, which it turn is dependent
on my extended class -- which I was trying to avoid. However, I understand
this may be my only option.
Helge Jensen wrote:
BTW: Are you in C#1 or 2?
1.1
Bob wrote:
You only need one collection. The one for the
base class.
Theoretically true, but I want my collections to be type-safe, so that
casting isn't required to access the extended members. However, if doing
this would remove the dependence of my data layer on my extended class, I
would go this route.
When you're pulling in data from the database
test the attribute(s) that mark the difference between
Mybase and MyExtendedBase before instantiating
the object that you are going to add to the collection.
This is similar to the factory concept, and requires the same dependency of
my data layer on my extended object/properties. The data layer will not
need access to any of the extended properties, so I would prefer to not
require this dependency. But again, I may not have that option.
Repeating what I said in my original post, here is my setup:
MyBase
MyBaseCollectio n
MyExtendedBase : MyBase
MyExtendedBaseC ollection : MyBaseCollectio n
I can pass an instance of MyExtendedBaseC ollection to the data layer, caste
as MyBaseCollectio n. But when my data layer creates new MyBase objects and
adds them to the collection, there's no way I can down-cast them to
MyExtendedBase when I return from the data layer. I would think there would
be a way to have a base collection get populated with base objects, without
introducing the dependency of the underlying method on the extended
class/collection. It seems this would be a common need, but it sounds like
my options aren't as elegant as "best practices" encourage.
Dkode, you mentioned interfaces. Would the use of interfaces help
accomplish my goals?
Thanks again.
Jerad
If you want "type safety" (more likely you want to avoid the upcast
here) then you should consider a move to 2.0 and generics. You can do
something similar to this, I've done it in my own data
objects/collections
Something like:
MyBaseObj{ }
MyBaseCollectio n<T> : ICollection<T> where T : MyBaseObj
{
public T this[int index]
{
get
{
...
}
}
...
}
Then MyDerivedObj :MyBaseObj for your derived record obj
and MyDerivedCollec tion : MyBaseCollectio n<MyDerivedObj > for your
derived collection of derived record objects
Thats interesting how you accomplish this with generics. I need to read
up more on generics. All I have used them for is for a List collection
within another class. What does using the <T> accomplish? You don't
have to specify the type?
dkode wrote: Thats interesting how you accomplish this with generics. I need to read up more on generics. All I have used them for is for a List collection within another class. What does using the <T> accomplish? You don't have to specify the type?
You don't specify the type when writing the generic type; you specify
it when you *use* the type.
It's well worth reading up on generics - it's a massive topic though!
Jon
For those interested, I am posting below what ended up being the ultimate
solution I came to. This accomplishes both of my goals:
1) Type safety
2) Independence of data layer on extended classes
Your feedback is welcomed and appreciated.
Thanks.
Jerad
//Polymorphic Collections Example
public class MyBaseClass
{
//base member implementation
}
public class MyBaseCollectio n : ICollection
{
protected ArrayList _innerList;
public MyBaseClass this[int index]
{
get { return (MyBaseClass)_i nnerList[index]; }
}
public virtual MyBaseClass AddNewItem()
{
MyBaseClass newBaseItem = new MyBaseClass();
_innerList.Add( newBaseItem);
return newBaseItem;
}
//standard collection member implementation
}
public class MyExtendedClass : MyBaseClass
{
public string MyExtendedPrope rty
{
//get/set implementation
}
}
public class MyExtendedColle ction : MyBaseCollectio n
{
public new MyExtendedClass this[int index]
{
get { return (MyExtendedClas s)base._innerLi st[index]; }
}
public override MyBaseClass AddNewItem()
{
MyExtendedClass newExtendedItem = new MyExtendedClass ();
_innerList.Add( newExtendedItem );
return newExtendedItem ;
}
}
public class MyDataLayer
{
public void GetRecords(MyBa seCollection myBaseCol)
{
//database implementation
while(dr.Read() )
{
//This is critical -- using the collection's AddNewItem
//to instantiate the object will ensure the proper type
//is being instantiated. If the collection is an
//instance of MyExtendedColle ction, it will create and
//add an instance of MyExtendedClass to the collection.
//Otherwise, it will add an instance of MyBaseClass.
MyBaseClass myBase = myBaseCol.AddNe wItem();
//set myBase's base properties
}
}
}
public class TestClient
{
public void Main()
{
MyDateLayer myDL = new MyDataLayer();
//This will pass an instance of a base collection to the data layer
MyBaseCollectio n myBaseCol = new MyBaseCollectio n();
myDL.GetRecords (myBaseCol);
myBaseCol[0].MyExtededPrope rty = "Not legal";
//This will pass an instance of an extended collection to the data
layer
MyExtendedColle ction myExtCol = new MyExtendedColle ction();
myDL.GetRecords (myExtCol);
myExtCol[0].MyExtededPrope rty = "Legal";
}
}
I have a quick question about your implementation.
Doesn't this violate n-tier design because the datalayer has knowledge
of the business layer objects? I thought the data layer was only
supposed to return records (DataReader) in this instance, or is all of
this code in your data layer? From other NG postings, I've had people tell me that the Data Layer has
NO knowledge of business layer objects, doing so violates proper N-Tier
design and tighly couples your business layer with your data layer. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: The Directive |
last post by:
I can't understand why in this folling example the message
"Base.Draw()" is printed. Shouldn't "Derive.Draw" be printed because
of polymorphism? How can I rewrite this example using a vector to
achieve polymorphism. Help!!! I'm very confused.
//Base class.
class Base
{
public:
Base()
|
by: Steve Jorgensen |
last post by:
The classing Visual Basic and VBA support for polymorphism, let's face it, is
a bit on the weak side, and built-in support for inheritance is non-existent.
This little essay is about some patterns I've ended up using successfully for
certain kinds of inheritance and polymorphism, and some that have not worked
out so well.
Let's start with obvious things that turn out not to work well:
1. Use interface classes and "Implements" for...
|
by: Marc |
last post by:
Given a class 'Invoice' with a property 'public IMyColl<IInvoiceLine>
InvoiceLines' where 'IMyColl<T> : IList<T>' i would like to detect by
reflection that 'InvoiceLines' is a 'System.Collection.Generic.IList'.
When performing something like: 'if
(typeof(IList<>).IsAssignableFrom(propertyInfo.Type))' where 'propertyInfo'
obviously refers to the 'InvoiceLines', the result is always 'false' because
indeed 'IList<object>' and...
|
by: rwf_20 |
last post by:
I just wanted to throw this up here in case anyone smarter than me has
a suggestion/workaround:
Problem:
I have a classic producer/consumer system which accepts 'commands' from
a socket and 'executes' them. Obviously, each different command (there
are ~20 currently) has its own needed functionality. The dream goal
here would be to remove all knowledge of the nature of the command at
runtime. That is, I don't want ANY switch/cases...
|
by: nhmark64 |
last post by:
Hi,
Does System.Collections.Generic.Queue not have a Synchronized
method because it is already in effect synchronized, or is the
Synchronized functionality missing from
System.Collections.Generic.Queue? Putting it another way can I
safely replace a
System.Collections.Queue.Synchronized(myUnSynchronizedQueue) with a
System.Collections.Generic.Queue while porting a working 2003 project?
Thanks,
| |
by: Krivenok Dmitry |
last post by:
Hello all!
Perhaps the most important feature of dynamic polymorphism is
ability to handle heterogeneous collections of objects.
("C++ Templates: The Complete Guide" by David Vandevoorde
and Nicolai M. Josuttis. Chapter 14.)
How to implement analogue of this technique via static polymorphism?
Perhaps there is special design pattern for this purpose...
|
by: James Crosswell |
last post by:
I'm not sure if I'm going about this the right way - it may be that
Generics might be able to help me out here... but here goes:
I have three classes as follows
class BaseEdit
class WidgetEdit: BaseEdit
class FooEdit: BaseEdit
These are all acutally Windows Forms and BaseEdit is an abstract class
(and so never gets instantiated). I'd like to define a method in
|
by: dippykdog |
last post by:
I have an IRange interface defined as...
Public Interface IRange
Property Min() As Object
Property Max() As Object
End Interface
....and I want to implement that in different kinds of range objects
like IntegerRange, StringRange, WeightRange, CurrencyRange, etc.
But I can't implement the interface using more specific types like
this
Public Class IntegerRange
|
by: mattmao |
last post by:
I am brand new to C#.NET so here is my trial on this lab exercise:
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace lab02exec
{
public class Program
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look !
Part I. Meaning of...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it.
Here is my compilation command:
g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Here is the code in...
| |
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth.
The Art of Business Website Design
Your website is...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own....
Now, this would greatly impact the work of software developers. The idea...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms.
Adolph will...
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...
| |