【问题标题】:Dynamic selection of method based on runtime parameter type基于运行时参数类型动态选择方法
【发布时间】:2013-06-10 22:53:14
【问题描述】:

我在过去看到过类似的问题/答案,但我的问题与我看到的其他问题略有不同。

本质上,我有一个通用接口和几个实现/继承它的类。然后,在一个单独的类中,我有必须作用于接口 IObject 给出的对象的方法。但是,它们中的每一个都必须以不同的方式进行操作,因此为什么对于扩展 IObject 的每个具体类型都有一个单独的方法声明。

class IObject
{
    ...
}

class ObjectType1 : IObject
{
    ...
}

class ObjectType2 : IObject
{
    ...
}

class FooBar
{
    void Foo (ObjectType1 obj);
    void Foo (ObjectType2 obj);
}

现在,对我来说,一个明显的解决方案是通过将方法 Foo 放在每个单独的类中来利用动态绑定,这将在运行时自动选择正确的 Foo 来执行。但是,这里 不是 一个选项,因为我正在定义多个模型来处理这些对象,我宁愿将每个单独的模型封装在其自己的类中处理对象,而不是全部填充将模型转换为对象类。

我发现this 帖子显示了如何使用字典在运行时动态选择正确的方法实现。我对这种方法很好;但是,假设我必须在每个模型中执行一次这样的调度。如果我只有 IObject 及其具体实现,有没有办法概括这种方法,以便我可以根据对象的运行时类型调用任何名称的方法?

我知道这可能是一个不清楚的问题,但我非常感谢任何帮助。

【问题讨论】:

    标签: c#


    【解决方案1】:

    dynamic 关键字实际上非常擅长:

    void Main()
    {
        var foobar = new FooBar();
        foreach(IObject obj in new IObject[]{ new ObjectType1(), new ObjectType2()})
        {
            foobar.Foo((dynamic)obj);
        }   
        // Output:
        //  Type 1
        //  Type 2
    }
    
    class IObject
    {
    }
    
    class ObjectType1 : IObject
    {
    }
    
    class ObjectType2 : IObject
    {
    }
    
    class FooBar
    {
        public void Foo (ObjectType1 obj) {
            Console.WriteLine("Type 1");
        }
        public void Foo (ObjectType2 obj) {
            Console.WriteLine("Type 2");
        }
    }
    

    代码超级简单,有pretty decent performance

    【讨论】:

    • 哦,哇,如果它的行为和它看起来一样,那就太棒了!当我有机会时,我会玩弄一点,但感谢这个解决方案。我的代码的重点是可读性和易于维护,所以这看起来非常棒。
    【解决方案2】:

    您可以只创建一种采用接口类型的方法,然后检查正确的类型 并投射它

    ObjectType1 obj1 = new ObjectType1();
    
    foo(obj1);
    
    void foo(IObject fm)
            {
                ObjectType1 cls;
                if (fm is ObjectType1)
                {
                    cls = fm as ObjectType1;
                    cls.ID = 10;
                    MessageBox.Show(cls.ID.ToString() + "    " + cls.GetType().ToString());
                } 
            }
    

    那是因为类实现了 IObject ,cls.ID 只是一个示例,您可以放置​​一个您实现的属性。 请尝试一下,然后告诉我....祝您好运。

    【讨论】:

    • 这是几天前采用的方法(因为我熟悉它并且需要演示工作)。现在我正在更广泛地解决这个问题,我正在探索可能特定于 C# 的其他更简单的选项。不过,这种方法确实有效!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-07
    • 2020-12-08
    • 1970-01-01
    • 2013-03-17
    相关资源
    最近更新 更多