Link to home
Start Free TrialLog in
Avatar of adavir
adavir

asked on

Inheritance : Assign a Parent Object to a Inherited Child Object.

Hi all,
I would like to assign a Parent Object to a Inherited Child Object. Is this possible.

Given a Parent and a Child Class A and B : A respectively

The assignments permitted for such as relationship by default are

A = (A) B

but B = (B) A is illegal

Is there a way around this that doesnt involve heavy implicit or expliciat operator functions.

Regards

Paul
Avatar of jonorossi
jonorossi

Not that I am aware of, this doesn't make a lot of sense. Maybe your inheritance hierarchy should be changed. I don't know if you know what you are saying, but it doesn't make sense to say every animal is a dog, however every dog is an animal. If you describe your classes I might be able to suggest something how you could change it or something else to convert a dog to an animal.
You can't do B = (B) A since B is more specific than A, however you could have a third class C with
B : C

then you can do:

B= (C)A
A= (C)B

 C could be object for example (all clases are childs of object in c#)
now that I think of it..that would not work neither, since it would give an error when executing because it is not in the right type.. No, there is no way to do it
Avatar of adavir

ASKER

Basically in my software

Every Member(user) has and Organisation that they are a member of

an organisation may be a Supplier, Shipper, Bond, Airport, Airline.

Depending in the type of organisation more specific attributes are required.

The types Supplier, Shipper, Bond, Airport, Airline inherit the type Organistaion.

The additional attributes that further defines the inheriting class are stored in the base Organisation Instance in the method OrganisationAttributes.

public class Supplier : Organisation
{
      /// <summary>
      /// Whether a supplier delivers their Own Products or not
      /// </summary>
      public bool SupplierDelivers
      {
            get
            {
                  return OrganisationAttributes[SupplierAttribute.SUPPLIER_DELIVERS];
            }
            set
            {
                  OrganisationAttributes[SupplierAttribute.SUPPLIER_DELIVERS] = value;
            }
      }
}

What complicates things a little is that all of my all of my organisations are located in a cached HashTable hashed by ID. So to fectah an Organisation very quickly I could go

Organisation tOrg = OrganisationStore.FromID(1827)   // and that would grab my organisation

however

Order.OrderSupplier = OrganisationStore.FromID(1827)  // Would not work

In a perfect world I would like to be able to Assign a Supplier to an Organisation and vice versa while maintaining the essential attributes in both cases. I thought my answer would lie in a few simple lines inside an Implicit opreator. but i guess not

Thanks for your input

But I dont think I can as in this ins



 
You can accomplish what you want to do. Instead of "assigning", I think you mean casting. Here's one way:
Order.OrderSupplier = OrganisationStore.FromID(1827)  as OrderSupplier;

If it is a different kind of organization, it will not throw a run-time exception. It will set:
Order.OrderSupplier = null;

So, if you know what kind of organization you are getting, that is enough. If not, then:
Supplier supplier = OrganisationStore.FromID(1827)  as Supplier;
Shipper shipper =  OrganisationStore.FromID(1827)  as Supplier;
etc.

At most one of them will be non-null. You could make it easer by adding something like OrganizationType to the Orgainization class, and set it from the derived class in the constructor. Then,
Organisation org = OrganisationStore.FromID(1827);
if (org.Organization == SupplierType)
   Order.OrderSupplier = org as Supplier;

Jim
Sorry last bit should be:
if (org.OrganizationType == SupplierType)
   Order.OrderSupplier = org as Supplier;

Jim
Avatar of adavir

ASKER

Thanks for the reply, i will have a look at it in the morning. After actually thinking about it I have a feelling that the answer lies with adding a base constructor in my inheriting classes.

I understand what you are suggesting but if you mean

Shipper shipper =  (Shipper) OrganisationStore.FromID(1827) ;

This will through an InValid cast exception, as you would expect. Maybe in VB it doesnt but CSharp definately does.

What I will try tomorrow is

public class Supplier : Organisation
{
      public Suppler() : base()
      {
           
      }

      public Supplier(Organisation pOrganisation) : base(Organisation pOrganisation)
      {
            // Nothing here
      }
}

But how can i populate my base class instance with the pOrganisation as...

public Organisation(Organisation pOrganisation)
{
      this = (Organisation) MemberwiseClone();
}


will definately not work, but may help you understand what I am trying to achieve. Whoever can answer this question solves the problem. (depending on how i get on in the morning with the base constructors.)

Regards

Paul


Don't cast like this:
Shipper shipper =  (Shipper) OrganisationStore.FromID(1827) ;

Instead, use this:
Shipper shipper =  OrganisationStore.FromID(1827) as Shipper ;
This retuns null if the cast is invalid, no exception thrown.

Make your constructors something like this:
public abstract class Organization
{
   public enum OrganizationType
   {
      None = 0,
      Supplier = 1,
      Shipper,
      Etc
   };

   private OrganizationType mType = OrganizationType.None;
   public OrganizationType OrgType
   {
      get
      {
         return mType;
      }
   }
   public Organization(OrganizationType orgType)
   {
      mType = orgType;
   }
}
public class Shipper : Organization
{
   public Shipper()
      : base(OrganizationType.Shipper)
   {
   }
}

Jim
Avatar of adavir

ASKER

Just tried your suggestion, it always returns NULL when assigning a Organisation to a Supplier.Thanks for pointing out what the "as" keyword is for I always thought it was a VB syntax of casting.

How can I overwrite the Current instance, I know the following wont work but is there a means of doing so?

public Organisation(Organisation pOrganisation)
{
      this = pOrganisation;
}

Regards Paul
Avatar of adavir

ASKER

Right, the answer for this is in the Base class Constructor. What I am trying to achieve is something like...

public Organisation(Organisation pOrganisation)
{
      this = pOrganisation;
}

How can this be achieved, if at all?

Paul
ASKER CERTIFIED SOLUTION
Avatar of JimBrandley
JimBrandley
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of adavir

ASKER

Hi Jim,

Thats what I was previously doing, i just thought that there might be a better way of doing it. But it looks like there isnt.

The problem with solution you provided is that every time i add a new method i have to update that function. I have been doing that for years and always felt that there was maybe a way of doing it in a more generic way.

also I found out today that you cant create an implicit conversion from base to parent class even using the solution you provided.

Anyways seen as it is the actual solution to problem its best to end the thread

Regards

Paul
I have a lot of code in production that works just like this:
Organisation org = OrganisationStore.FromID(1827);
if (org.OrgType == SupplierType)
   Order.OrderSupplier = org as Supplier;

with no problems.

Jim
Avatar of adavir

ASKER

hmmm, everytime I ran it i got null everytime. I really tried to get that working spent 3 hours with your suggestion.

Thanks for your help