如何从接口访问派生的类成员?
-
21-09-2019 - |
题
我有三个课;邮票,字母和包裹实现接口iProduct,它们也具有自己的一些功能。
public interface IProduct
{
string Name { get; }
int Quantity { get; set; }
float Amount { get; }
}
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 class Letter : IProduct
{
public string Name { get { return "Letter"; } }
public int Quantity { get; set; }
public float Amount { get; set; }
public float Weight { get; set; }
public string Destination { get; set; }
}
public class Parcel : IProduct
{
public string Name { get { return "Parcel"; } }
public int Quantity { get; set; }
public float Amount { get; set; }
public float Weight { get; set; }
public string Destination { get; set; }
public int Size { get; set; }
}
public static class ShoppingCart
{
private static List<IProduct> products = new List<IProduct>();
public static List<IProduct> Items { get { return products; } }
}
为什么我不能从一个 List<IProduct>
?
ShoppingCart.Items.Add(new Stamp { Quantity = 5, UnitPrice = 10, Amount = 50 });
ShoppingCart.Items.Add(new Letter { Destination = "US", Quantity = 1, Weight = 3.5f });
ShoppingCart.Items.Add(new Parcel { Destination = "UK", Quantity = 3, Weight = 4.2f, Size = 5 });
foreach (IProduct product in ShoppingCart.Items)
{
Console.WriteLine("Name: {0}, Quantity: {1}, Amount: {2}", product.Name, product.Quantity, product.Amount);
}
我想到了使用仿制药,但是在这种情况下,我必须为每种特定类型的产品编写单独的代码。
public static class ShoppingCart<T> where T : IProduct
{
private static List<T> items = new List<T>();
public static List<T> Items { get { return items; } }
}
ShoppingCart<Stamp>.Items.Add(new Stamp { Quantity = 5, Amount = 10, UnitPrice = 50 });
ShoppingCart<Letter>.Items.Add(new Letter { Destination = "US", Quantity = 1, Weight = 3.5f });
foreach (Stamp s in ShoppingCart<Stamp>.Items)
{
Console.WriteLine("Name: {0}, Quantity: {1}, Amount: {2}", s.Name, s.Quantity, s.Amount);
}
foreach (Letter l in ShoppingCart<Letter>.Items)
{
Console.WriteLine("Name: {0}, Destination: {1}, Weight: {2}", l.Name, l.Destination, l.Weight);
}
对于这种问题,没有任何设计模式。工厂模式?
解决方案
这是因为您将每件商品都铸在购物车中,作为foreach循环中的iProduct。您需要做的就是这样的事情:
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);
}
}
您也正在重复不必要的属性 名称,数量和数量. 。您应该从产品中得出每个类:
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; }
}
其他提示
您无法访问实现接口的类的其他成员 IProduct
在项目列表中。我将为购物车中的每个项目添加特定的列表类型,然后在购物车课上,然后您可以将购物车中所有产品的序列显示为只需要使用Iproduct界面的任何东西:
public class ShoppingCart
{
public IList<Stamp> Stamps { get; }
public IList<Letter> Letters { get; }
public IList<Parcel> Parcels { get; }
public IEnumerable<IProduct> Products
{
get
{
return this.Stamps.Cast<IProduct>()
.Concat(this.Letters.Cast<IProduct>())
.Concat(this.Parcels.Cast<IProduct>());
}
}
}
为什么我不能从一个
List<IProduct>
?
那是因为, IProduct
界面不知道 UnitPrice
, Destination
派生类属性的等等。
您是否尝试添加智能来计算 Amount
到每个派生的类对象邮票,字母,包裹?
然后,我会说您需要重新设计一点并使用 装饰器设计图案.
DerivedClass::Amount()
{
Base::Amount() +
//Amount logic based on derived class
}
您无法从派生类中访问其他成员的原因是您使用列表<>中的接口 - 因此,您只能访问该接口上的属性。
可能会帮助您的模式是双分配模式。
下面的示例:
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);
}
}
现在,您可以在处理程序中编程一些特定功能 - 我猜您想计算某种总价给定的东西,例如数量 *单位价格或重量和目的地查找表...
不隶属于 StackOverflow