我有代码:
foreach(var o in objects)
{
o.Update(time);
if(o is Portal)
{
var a = (Portal)o;
a.Interact(ref player, player.Interact);
}
else if(o is Enemy)
{
var e = (Enemy)o;
e.Update(time, player);
}
}
我不知道这样的事情是否可行?
我想在一行中完成。 这就是我的想法:
(Enemy)o => Update(time, player);
我知道这很愚蠢,但我想要类似的东西。将播放器作为参数的方法对于Enemy对象是唯一的。我必须解析才能打电话。
答案 0 :(得分:7)
您可以简化循环(如果您使用C#6或更高版本):
foreach(var o in objects)
{
o.Update(time);
(o as Portal)?.Interact(ref player, player.Interact);
(o as Enemy)?.Update(time, player);
}
对于C#5或更低版本,您应该使用:
foreach(var o in objects)
{
o.Update(time);
if (o is Portal)
{
((Portal)o).Interact(ref player, player.Interact);
}
else if(o is Enemy)
{
((Enemy)o).Update(time, player);
}
}
在这种情况下,您的代码行数较少,但是您投了两次。
你只能投一次:
foreach(var o in objects)
{
o.Update(time);
var e = o is Portal;
if (e != null)
{
e.Interact(ref player, player.Interact);
}
else
{
((Enemy)o).Update(time, player);
}
}
答案 1 :(得分:3)
答案 2 :(得分:3)
您可以用一行代替这两行:
else if(o is Enemy)
{
((Enemy)o).Update(time, player);
}
答案 3 :(得分:2)
你以这种方式调用函数:
var a = ((Portal)o).Interact(ref player, player.Interact);
因此,a的类型将是返回的Interact类型,但在代码的上下文中,它将无关紧要。
答案 4 :(得分:1)
要比其他回复更进一步,您可以使用visitor pattern。
首先创建一个IVisitorClient
和一个IVisitor
界面。
interface IVisitorClient
{
Accept(IVisitor visitor);
}
interface IVisitor
{
Visit(SceneObject o); // here the types of your objects
Visit(Enemy e);
Visit(Portal p);
}
使您的不同对象实现IVisitorClient
。
abstract class SceneObject : IVisitorClient
{
public virtual void Accept(IVisitor visitor)
{
visitor.Visit(this);
}
}
class Portal : SceneObject
{
...
public override void Accept(IVisitor visitor)
{
visitor.Visit(this);
}
...
}
class Enemy: SceneObject
{
...
public override void Accept(IVisitor visitor)
{
visitor.Visit(this);
}
...
}
然后构建一个实现IVisitor
的更新程序:
class UpdaterVisitor : IVisitor
{
readonly Player player;
readonly Time time;
public UpdaterVisitor(Player player, Time time)
{
this.player = player;
this.time = time;
}
public void Visit(SceneObject o)
{
e.Update(time);
}
public void Visit(Enemy e)
{
e.Update(time, player);
}
public void Visit(Portal p)
{
p.Interact(ref player, player.Interact);
}
}
最后,要更新对象,代码将如下所示。
var updateVisitor = new UpdaterVisitor(player, time);
foreach(var o in objects)
{
o.Accept(updateVisitor);
}
答案 5 :(得分:0)
或者这样做以避免双重演绎...
foreach(var o in objects)
{
o.Update(time);
Portal p = o as Portal;
if(p != null)
{
p.Interact(ref player, player.Interact);
}
else
{
Enemy e = o as Enemy;
if (e != null)
{
e.Update(time, player);
}
}
}