C# 不同参数类型的相同方法

C# Same methods for different argument type

提问人:ProtoTyPus 提问时间:2/4/2023 更新时间:2/4/2023 访问量:58

问:

我有这个接口:

public interface ICommand
{
    bool Execute(Vector2 commandPosition);
    bool Execute(GameUnit gameUnit);
    bool Execute(string shortcut);
}

以及具有这些方法的类,使用不同的参数类型进行相同的操作

private void DispatchGameUnitCommand(GameUnit gameUnit)
{
    if (_preparedCommand != null)
    {
        _preparedCommand.Execute(gameUnit);
        return;
    }
    for (int i = 0; i < _commands.Length; i++)
    {
        if (_commands[i].Execute(gameUnit))
        {
            return;
        }
    }
}

private void DispatchLocationCommand(Vector2 screenPosition)
{
    if (_preparedCommand != null)
    {
        _preparedCommand.Execute(screenPosition);
        return;
    }
    for (int i = 0; i < _commands.Length; i++)
    {
        if (_commands[i].Execute(screenPosition))
        {
            return;
        }
    }
}

private void DispatchShortcutCommand(string shortcut)
{
    if (_preparedCommand != null)
    {
        _preparedCommand.Execute(shortcut);
        return;
    }
    for (int i = 0; i < _commands.Length; i++)
    {
        if (_commands[i].Execute(shortcut))
        {
            return;
        }
    }
}

我怎样才能改进它们删除重复的代码?无论如何可能吗?

C# 重构 可读性

评论


答:

0赞 IVSoftware 2/4/2023 #1

你的帖子说你有“一个具有这些方法的类”,用于 和 。GameUnitVector2string

代码示例中的所有迹象都表明,执行任何操作都需要实际值。在这种情况下,“可能”真正有帮助的是具有隐式转换运算符,这些运算符将 a 或 a 转换为 .GameUnitstringVector2GameUnit


具有隐式转换的 GameUnit

public class GameUnit
{
    public Vector2 Vector2 { get; set; }
    public string? Name { get; set; }
    public static Dictionary<string, GameUnit> Shortcuts { get; }
        = new Dictionary<string, GameUnit>();

    public static implicit operator GameUnit(Vector2 vector)
    {
        return new GameUnit { Vector2 = vector };
    }

    public static implicit operator GameUnit(string shortcut)
    {
        Shortcuts.TryGetValue(shortcut, out GameUnit gameUnit);
        return gameUnit; // Will be null if not in dict
    }

    public override string ToString() => $"{Vector2} {Name}";
}

按照这个逻辑,我们最终会得到一个调度程序类,它只需要一个方法,而不是三个方法。

public class Dispatcher
{
    public void DispatchGameUnitCommand(GameUnit context)
    {
        Console.WriteLine($"Dispatching {context}");
    }
}

至于,你打算如何使用它?到目前为止,它不需要做任何事情。interface


测试

static void Main(string[] args)
{
    Console.Title = "GameUnit Test";
    Dispatcher exec = new Dispatcher();
    GameUnit
        adHoc = new GameUnit { Name = "AdHoc", Vector2 = new Vector2(5000, 2000) },
        vectorA = new GameUnit { Name = "VectorA", Vector2 = new Vector2(5, 20) };
    GameUnit.Shortcuts[adHoc.Name] = adHoc;
    GameUnit.Shortcuts[vectorA.Name] = vectorA;

    exec.DispatchGameUnitCommand(adHoc);
    exec.DispatchGameUnitCommand("VectorA");
    exec.DispatchGameUnitCommand(new Vector2(500, 200));
}

console output

评论

0赞 IVSoftware 2/4/2023
顺便说一句,考虑重命名为其他内容(任何内容)。这很可能会引发大规模的冲突。ICommandSystem.Windows.Input.ICommand