用更多派生参数调用重载函数的更好方法,传递较少派生的类型

本文关键字:派生 类型 方法 更好 参数 调用 重载 函数 | 更新日期: 2023-09-27 18:22:04

我有16个方法,它们接受两个参数,这两个参数中的每一个都可以是"Insertion"或"Delegation",它们都实现IFragment。我还有四个类似的助手功能:

    static IFragment[] IntroduceAntecedent(IFragment on, IFragment item) {
        bool onIsInsertion = on is Insertion;
        bool itemIsInsertion = item is Insertion;
        if (onIsInsertion) {
            if (itemIsInsertion) {
                return IntroduceAntecedent((Insertion) on, (Insertion) item);
            } else {
                return IntroduceAntecedent((Insertion) on, (Deletion) item);
            }
        }
        else {
            if (itemIsInsertion) {
                return IntroduceAntecedent((Deletion)on, (Insertion)item);
            } else {
                return IntroduceAntecedent((Deletion)on, (Deletion)item);
            }
        }
    }

它只不过是确定实际类型并调用适当的重载。有更干净的方法吗?换句话说,我可以用派生类型较少的对象调用函数的派生重载吗?

编辑:介绍人Antecedent的签名重载

static IStringTransform[] IntroduceAntecedent(Deletion lhs, Deletion rhs)
static IStringTransform[] IntroduceAntecedent(Deletion lhs, Insertion rhs)
static IStringTransform[] IntroduceAntecedent(Insertion lhs, Deletion rhs)
static IStringTransform[] IntroduceAntecedent(Insertion lhs, Insertion rhs)

用更多派生参数调用重载函数的更好方法,传递较少派生的类型

我已经实现了DynamicDispatcher.cs,它满足了这一需求。

它使用反射和堆栈跟踪(构造中的单个跟踪)按参数类型生成重载树。它处理基类和已实现接口上的双向转换。

由于它是一个更大项目的一部分,并且没有任何文档,因此这里有一个示例用法(来自同一项目):

    public static void DeleteTreeNodeChild(BehaviorTree.Choice parentNode, BehaviorTree.Node childNode) {
        parentNode.Children.Remove(childNode);
    }
    public static void DeleteTreeNodeChild(BehaviorTree.Optional parentNode, BehaviorTree.Node childNode) {
        Debug.Assert(parentNode.Child == childNode);
        parentNode.Child = null;
    }
    public static void DeleteTreeNodeChild(BehaviorTree.Repetition parentNode, BehaviorTree.Node childNode) {
        Debug.Assert(parentNode.Child == childNode);
        parentNode.Child = null;
    }
    public static void DeleteTreeNodeChild(BehaviorTree.Sequence parentNode, BehaviorTree.Node childNode) {
        parentNode.Children.Remove(childNode);
    }
    private static DynamicDispatcher _deleteTreeNodeChildDynamicDispatcher;
    public static void DeleteTreeNodeChild(BehaviorTree.Node parentNode, BehaviorTree.Node childNode) {
        if (_deleteTreeNodeChildDynamicDispatcher == null) {
            _deleteTreeNodeChildDynamicDispatcher = new DynamicDispatcher();
        }
        _deleteTreeNodeChildDynamicDispatcher.Dispatch<Object>(null, parentNode, childNode);
    }

首先,您不能用"派生程度较低"的对象调用方法,因为您正在调用的方法正在等待该类型的最低要求。

对于这种类型的问题,我认为最好为该函数使用不同的名称。"IntroductAntecedent"应与"IntroduceAntecedent_DelDel"和所有其他3个组合一起存在。这显然是我自己的观点,但你做这件事的方式似乎符合你的预期。