我遇到了一个问题,我将多个项目传递给不同的类,但是同一个父类作为类构造函数的params,然后将它们分配给新类的变量:
public class Tool {}
public class Hammer:Tool {}
public class Screwdriver:Tool{}
所以我的工具类都继承自父工具类。现在我想创建一个工具箱,我存储我的工具;但是,我不会总是想用一套完整的工具制作它,所以我传递了一个参数数量未定义的参数:
public class Toolbox{
public Hammer hammer;
public Screwdriver screwdriver;
public Toolbox(params Tool[] tool){
foreach (Tool t in tool){
switch (t.getType().Name){
case "Hammer":
hammer = t;
break;
case "Screwdriver":
screwdriver = t;
break;
}
}
}
这会导致编译器说它不能隐式转换'工具' to' Hammer',但可以使用显式转换"。 在这种情况下可能出现什么问题,是否有可能以一种简单的方式解决?
答案 0 :(得分:2)
每当你使用大量case/switch
时,你应该把它当作一个警告标志,表明你没有按照OO的方式做事。
执行此操作的OO方法是为Tool
定义公共属性,并在选择插槽时仅使用该属性。然后在子类中设置位置,如下所示:
Enum Location { Big, Large, Small, Drawer, Hanging}
class Tool
{
public abstract Location Location { get; }
}
class Hammer
{
public override Location { get { return Location.Top; } }
}
现在您的工具箱代码很简单:
class Toolbox
{
public readonly List<Location,List<Tool>> Store = new List<Location,List<Tool>>();
public Toolbox(params Tool[] tool)
{
foreach (Tool t in tool)
this.Store[t.Location].Add(t);
}
}
如果你需要更多的复杂性,可以将逻辑放入后代类中:
class Tool
{
public abstract void StoreIn(Toolbox toolbox);
}
class Hammer
{
public override void StoreIn(Toolbox toolbox)
{
toolbox.TopDrawer.Add(this);
}
}
同样,您的工具箱代码很简单:
class Toolbox
{
public void AddTools(params Tool[] tool)
{
foreach (Tool t in tool) t.StoreIn(this);
}
}
答案 1 :(得分:1)
问题是你知道它是Hammer
,但编译器只知道它是Tool
。正如错误消息所说,解决这个问题的方法是使用显式转换:
hammer = (Hammer)t;
通过此演员,您告诉编译器t
实际上是Hammer
答案 2 :(得分:1)
你能试试吗?此演员操作可以为您提供预期的结果。您可以访问并使用derived class
属性
编辑回答并添加了@ ja72 recomendation
foreach (Tool t in tool)
{
// option 1
if (t is Hammer)
{
Hammer hammer = t as Hammer;
.....
}
// option 2 @ja72 recomendation
if (t is Screwdriver screwdriver)
{
.......
}
}
答案 3 :(得分:0)
在现代C#中,您可以检查类型:
public class Toolbox
{
readonly Hammer hammer;
readonly Screwdriver screwdriver;
public Toolbox(params Tool[] tool)
{
foreach (Tool t in tool)
{
if (t is Hammer hammer)
{
this.hammer = hammer;
}
if (t is Screwdriver screwdriver)
{
this.screwdriver = screwdriver;
}
}
}
#region Properties
public Screwdriver Screwdriver => screwdriver;
public Hammer Hammer => hammer;
public bool HasHammer => hammer != null;
public bool HasScrewdriver => screwdriver != null;
#end region
}
构造x is Hammer
是一个布尔值,用于测试x
是Hammer
类型。如果if(x is Hammer y) { }
是x
类型,则用作Hammer
时,y
语句范围内的if
变量将引用它。
答案 4 :(得分:0)
根据您的Toolbox类,它最多可以包含1个Hammer和最多1个Screwdriver。让我们忽略你将变量定义为公共的那一刻;您可以使用以下类定义获得几乎相同的效果:
public class Toolbox {
public Hammer Hammer { get; set;}
public Screwdriver Screwdriver { get; set;}
public Toolbox() { }
}
然后而不是写(假设你已经定义了一个名为hammer的变量):
Toolbox t = new Toolbox(hammer);
你可以写:
Toolbox t = new Toolbox() { Hammer = hammer };
如果您需要添加其他工具,只需向Toolbox类添加新属性即可。