2

I have two classes Product and ExtendedProduct. ExtendedProduct is derived from Product class. There are some more fields in ExtendedProduct class.

The problem is that when i cast ExtendedProduct into Product my Product object has the fields that ExtendedProduct has.

I just want to convert ExtendedProduct to Product class without any ExtendedProduct class' field appearing in Product class.

Michael
  • 1,453
  • 3
  • 20
  • 28
MOD
  • 1,070
  • 3
  • 19
  • 41
  • 1
    Map the properties of `ExtendedProduct` to a new instance of `Product` –  Jan 29 '16 at 08:09
  • 2
    Code will help to explain the phenomenon... – Ian Jan 29 '16 at 08:10
  • 1
    It's a violation of [polymorphism](https://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29)! The only way to do this is creating a constructor in `Product` class that accept an `ExtendedProduct` object as parameter. – erikscandola Jan 29 '16 at 08:10
  • Further reading: [Variance and Contravariance](https://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29) – ardila Jan 29 '16 at 09:52

5 Answers5

8

As long as your ExtendedProduct IS a Product casting it to the latter won´t change anything to the casted instance because you reference the same object. So after all you just look at the same object from another perspective.

In order to decouple your object from its base-type you´d need to create a clone, a completely new instance of Product, e.g. by using a copy-constructor:

class Product {
    public Product(Product p) {
        this.MyProp = p.MyProp;   
    }
}

Now you can call this like:

var product = new Product(myExtended);

Now both objects are completely unrelated, changing MyProp on one doesn´t affect the other (in fact it does, if MyProp is a reference-type, so you´d need a deep clone instead).

However this sounds quite weird to me. Why would you want to "delete" the extended properties at all? You´ll need all the extra-information you provided earlier. You can simply cast to the parent-class which does not provide those properties at all:

var p = (Product) myExtendedProduct;

Now although p actually IS an instance of ExtendedProduct you can only access the properties from Product. This is a basic priciple of Polymorphism.

MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111
  • 6
    I guess OP will serialize the instance in the next step, that's why he doesn't want the unnecessary properties/fields. – Cheng Chen Jan 29 '16 at 08:25
1

You could write an extension for the ExtendedProduct class and handle your mapping there:

public static Product ToProduct(this ExtendedProduct extProduct)
{
   var product = new Product();
   product.par1 = extProduct.Par1;
   // ...

   return product;
}

and then call it like this:

var myExtProduct = new ExtendedProduct();
var product = myExtProduct.toProduct();
croxy
  • 4,082
  • 9
  • 28
  • 46
0

I think you want :

ExtendedProduct product = new ExtendedProduct();
Product p = product;

If you are not sure about conversion you can always do this :

ExtendedProduct product = new ExtendedProduct();
Product p = product as Product;

It is detailed here

MaLiN2223
  • 1,290
  • 3
  • 19
  • 40
0

Directly casting to the parent class will just change the way it is referred and not the structure. The below code snippet is something that you might find helpful. I am using JsonConvert for keeping it short. You can try to copy individual fields and generate a copy if you don't use Newtonsoft.

class ExtendedProduct : Product 
{
    object notrequired { get; set; }

    static Product copy(ExtendedProduct extendedProduct)
    {
        var orig = JsonConvert.SerializeObject(extendedProduct);
        Product copy = JsonConvert.DeserializeObject<Product>(orig);
        return copy;
    }
}

Just pass your ExtendedProduct object to the copy method which is static. You will get the required output.

stop-cran
  • 4,229
  • 2
  • 30
  • 47
Nitesh
  • 31
  • 4
-1

You can also add a method to the base class that returns the base as the class of the base.

Public Class Base
{
    Public Base GetBase()
    {
        return (Base)this;
    }
}

Now if this base class is inherited. You can call that method from it and get the Base class returned.

Parrish
  • 159
  • 5