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

C# 使用更多派生参数调用重载函数的更好方法,传递较少的派生类型,c#,inheritance,overloading,C#,Inheritance,Overloading,我有16个采用两个参数的方法,两个参数中的每一个都可以是“插入”或“删除”,这两个参数都实现了IFragment。我还有四个助手函数,如下所示: static IFragment[] IntroduceAntecedent(IFragment on, IFragment item) { bool onIsInsertion = on is Insertion; bool itemIsInsertion = item is Insertion;

我有16个采用两个参数的方法,两个参数中的每一个都可以是“插入”或“删除”,这两个参数都实现了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);
            }
        }
    }
它只不过是确定实际类型并调用适当的重载。有没有更干净的方法?换句话说,我可以用派生类型较少的对象调用函数的派生重载吗

编辑:IntroductEvent重载的签名

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)

首先,您不能使用派生较少的对象调用方法,因为您正在调用的方法正在等待此类型的最低要求

对于这种类型的问题,我认为最好对该函数使用不同的名称。IntroducteCentent应与IntroducteCentent_DelDel和所有其他三个组合一起存在。这显然是我自己的观点,但您这样做似乎符合您的期望。

我已经实现了满足这一需求的功能

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

由于它是一个较大项目的一部分,并且没有任何文档,因此下面是一个使用示例:


你也能分享一下IntroducteAntextent的样子吗。。这有助于真正理解您试图做的事情并简化它。我已经添加了签名。如果我理解正确,您应该能够使用提供的签名将4个IntroducteCentedent方法定义为扩展方法,并简单地调用它们以获得正确的方法invokedI宁愿继续最初的尝试而不是现在的尝试,虽然根本问题似乎是你的课程的设计问题。你能详细说明一下吗三是实现运行时绑定的更简单方法,就像使用dynamic关键字一样。我认为我的观点是,在您的情况下根本不需要运行时绑定,只是接口或更专业的接口应该提供所有必需的功能,以实现IntroducteCentent所做的任何事情。
    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);
    }