使用更多派生参数调用重载函数的更好方法,传入较少派生类型 [英] Better way to call overloaded functions with more-derived parameters, passing in less-derived types

查看:56
本文介绍了使用更多派生参数调用重载函数的更好方法,传入较少派生类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 16 个方法接受两个参数,这两个参数中的每一个都可以是插入"或删除",它们都实现了 IFragment.我也有四个这样的辅助函数:

I have 16 methods that take two parameters, and each of the two parameters can be either an 'Insertion' or a 'Deletion', both of which implement IFragment. I also have four helper functions like this:

    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);
            }
        }
    }

它只是确定实际类型并调用适当的重载.有没有更干净的方法来做到这一点?换句话说,我可以使用派生程度较低的对象调用函数的派生程度较高的重载吗?

It does nothing more than determine the actual types and call the appropriate overload. Is there a cleaner way to do this? Worded another way, can I call more-derived overload of a function with objects that are of a less-derived type?

IntroduceAntecedent 重载的签名

The signatures of the IntroduceAntecedent overloads

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 满足了这一需求.

I've implemented DynamicDispatcher.cs which fulfills this need.

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

It uses reflection and a stack trace (a single one on construction) to generate a tree of overloads by parameter types. It handles bidirectional casting on base classes and implemented interfaces.

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

Since it's part of a larger project and doesn't have any documentation, here's an example use (from the same project):

    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);
    }

这篇关于使用更多派生参数调用重载函数的更好方法,传入较少派生类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆