This is because you are casting each Item in the shopping cart as IProduct in your foreach loop. What you would need to do is something like: foreach(IProduct product in ShoppingCart. Items) { if (product is Stamp) { var stamp = product as Stamp; Console.
WriteLine("Name: {0}, Quantity: {1}, Amount: {2}, UnitPrice: {3}", stamp. Name, stamp. Quantity, stamp.
Amount, stamp. UnitPrice); } else if (product is Letter) { var letter = product as Letter; Console. WriteLine("Name: {0}, Quantity: {1}, Amount: {2}, Weight: {3}, Destination: {4}", letter.Name, letter.
Quantity, letter. Amount, letter. Weight, letter.
Destination); } else if (product is Parcel) { var parcel = product as Parcel; Console. WriteLine("Name: {0}, Quantity: {1}, Amount: {2}, Weight: {3}, Destination: {4}, Size: {5}", parcel.Name, parcel. Quantity, parcel.
Amount, parcel. Weight, parcel. Destination, parcel.
Size); } } Also you are repeating unnecessary properties Name, Quantity and Amount You should derive each of your classes from Product: public class Stamp: Product, IProduct { public double UnitPrice { get; set; } } public class TransitProduct: Product, IProduct { public double Weight { get; set; } public string Destination { get; set; } } public class Letter: TransitProduct, IProduct { } public class Parcel: TransitProduct, IProduct { public double Size { get; set; } }.
This is because you are casting each Item in the shopping cart as IProduct in your foreach loop. What you would need to do is something like: foreach(IProduct product in ShoppingCart. Items) { if (product is Stamp) { var stamp = product as Stamp; Console.
WriteLine("Name: {0}, Quantity: {1}, Amount: {2}, UnitPrice: {3}", stamp. Name, stamp. Quantity, stamp.
Amount, stamp. UnitPrice); } else if (product is Letter) { var letter = product as Letter; Console. WriteLine("Name: {0}, Quantity: {1}, Amount: {2}, Weight: {3}, Destination: {4}", letter.Name, letter.
Quantity, letter. Amount, letter. Weight, letter.
Destination); } else if (product is Parcel) { var parcel = product as Parcel; Console. WriteLine("Name: {0}, Quantity: {1}, Amount: {2}, Weight: {3}, Destination: {4}, Size: {5}", parcel.Name, parcel. Quantity, parcel.
Amount, parcel. Weight, parcel. Destination, parcel.
Size); } } Also you are repeating unnecessary properties Name, Quantity and Amount. You should derive each of your classes from Product: public class Stamp: Product, IProduct { public double UnitPrice { get; set; } } public class TransitProduct: Product, IProduct { public double Weight { get; set; } public string Destination { get; set; } } public class Letter: TransitProduct, IProduct { } public class Parcel: TransitProduct, IProduct { public double Size { get; set; } }.
You can't access the additional members of classes which implement an interface because you're only exposing IProduct in the List of items. I'd add specific list types for each item in the shopping cart to the ShoppingCart class, and then you can expose a sequence of all the products in the cart for anything which only needs to use the IProduct interface: public class ShoppingCart { public IList Stamps { get; } public IList Letters { get; } public IList Parcels { get; } public IEnumerable Products { get { return this.Stamps.Cast() . Concat(this.Letters.Cast()) .
Concat(this.Parcels.Cast()); } } }.
– RK. Nov 23 '09 at 13:19 Yes, but the effect will be the same in this case – Lee Nov 23 '09 at 13:46.
That is because, IProduct interface does not know about UnitPrice, Destination etc of the derived class properties. Are you trying add the intelligence to calculate the Amount to each of the derived class objects Stamp, Letter, Parcel? Then, I would say you need to redesign a bit and use the Decorator design pattern.
DerivedClass::Amount() { Base::Amount() + //Amount logic based on derived class }.
The reason why you can't access additional members from a derived class is that you are using the interface in the List - therefore you'll only be able to access properties on that interface. A pattern that might help you is the double-dispatch pattern. Example below: public interface IHandler { void Handle(Stamp stamp); void Handle(Letter letter); ... } public class Handler : IHandler { public void Handle(Stamp stamp) { // do some specific thing here... } public void Handle(Letter letter) { // do some specific thing here... } ... } public interface IProduct { string Name { get; } int Quantity { get; set; } float Amount { get; } void Handle(IHandler handler); } public class Stamp : IProduct { public string Name { get { return "Stamp"; } } public int Quantity { get; set; } public float Amount { get; set; } public float UnitPrice { get; set; } public void Handle(IHandler handler) { handler.
Handle(this); } } You can now program some specific functionality in the Handler - I'm guessing you want to calculate some kind of total price given things such as quantity * unit price or a weight & destination lookup table...
Thanks Codebrain. Can you please provide any example/link or double-dispatch pattern in C#? – RK.
Nov 23 '09 at 13:10 Nice Codebrain. Thanks :) – RK. Nov 23 '09 at 13:38.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.