基于运行时参数类型的方法动态选择

时间:2013-06-10 22:53:15

标签: c#

我在过去发现了类似的问题/答案,但我与其他人的看法略有不同。

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

class IObject
{
    ...
}

class ObjectType1 : IObject
{
    ...
}

class ObjectType2 : IObject
{
    ...
}

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

现在,对我而言,一个显而易见的解决方案是通过将方法Foo放在每个单独的类中来利用动态绑定,这将在运行时自动选择要执行的正确Foo。但是,这是一个选项,因为我定义了多个模型来处理这些对象,我宁愿封装每个单独的模型来处理它自己的类中的对象,而不是所有的东西。将模型放入对象类中。

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

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

3 个答案:

答案 0 :(得分:10)

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

答案 1 :(得分:2)

也许你想要一些非常接近visitor patter的东西。

如果您只想按参数类型选择对象(Foo)的方法(FooBar),可以使用反射来获取具有给定名称(Foo)的所有方法,根据对象类型(ObjectTypeX)和参数选择进行参数的手动匹配。不要忘记正确处理派生类。

避免支付每次调用的反射成本 - 缓存结果(即通过构建/编译表达式树)。

请注意,Dictionary(按类型索引的给定方法名称的操作)方法可能更容易支持/调试开始。如果你发现它的需求很慢,你可以用更复杂的东西代替反射。

答案 2 :(得分:0)

你可以创建一个采用接口类型的方法,然后检查正确的类型 并施展它

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只是一个示例,您可以放置​​一个您实现的属性。 请尝试一下,让我知道....祝福。