如何从接口访问派生类成员?
我有三门课; Stamp、Letter 和 Parcel 实现了 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
访问派生类的其他成员?
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);
}
难道就没有一种设计模式可以解决这种问题吗?工厂模式?
I have three classes; Stamp, Letter and Parcel that implement an interface IProduct and they also have some of their own functionality.
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; } }
}
Why can't I access the additional members of derived classes from a 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);
}
I thought of using generics, but in that case I will have to write separate code for each specific type of product.
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);
}
Isn't there any kind of design pattern for this kind of problem. Factory Pattern?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您无法访问实现接口的类的其他成员,因为您仅在项目列表中公开
IProduct
。我将购物车中每个项目的特定列表类型添加到 ShoppingCart 类,然后您可以为仅需要使用 IProduct 接口的任何内容公开购物车中所有产品的序列: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:这是因为您在 foreach 循环中将购物车中的每个项目转换为 IProduct。您需要做的是这样的:
或者,C# 中现在提供了这种更现代的语法,它将
is
运算符与变量声明相结合:此外,您还重复了不必要的属性 Name、Quantity和金额。您应该从 Product 派生每个类:
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:
Alternatively, this more modern syntax now available in C#, which combines the
is
operator with the variable declaration:Also you are repeating unnecessary properties Name, Quantity and Amount. You should derive each of your classes from Product:
这是因为,
IProduct
接口不知道派生类属性的UnitPrice
、Destination
等。您是否正在尝试添加智能来计算每个派生类对象 Stamp、Letter、Parcel 的
Amount
?然后,我想说你需要重新设计一下并使用 装饰器设计模式。
That is because,
IProduct
interface does not know aboutUnitPrice
,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.
无法从派生类访问其他成员的原因是您正在使用 List<> 中的接口。 - 因此您只能访问该界面上的属性。
可能对您有帮助的模式是双调度模式。
下面的示例:
您现在可以在处理程序中编写一些特定的功能 - 我猜您想计算某种总价,例如数量 * 单价或重量和重量。目的地查找表...
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:
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...