c# – 通用重载决策

我有以下情况:

class Foo { }

class Foo<T> : Foo { }

然后是两种方法

void DoStuff(Foo foo) 
{
     DoStuffImpl(foo);
}

void DoStuffImpl(Foo foo) 
{ 
     Console.WriteLine("A");
}    
void DoStuffImpl<T>(Foo<T> foo) 
{ 
     Console.WriteLine("B");
} 

void Main() 
{
     DoStuff(new Foo<int>()); // prints A
}

(注意,代码是在浏览器中编写的,但描述了我面临的情况)

如何让它调用泛型方法,然后打印B?

这可以在没有反思的情况下完成吗?关于如何用反射完成,我有一些想法,但我正在寻找一个更清洁的解决方案,如果存在的话.

注意:我不能使DoStuff泛型,因为它将与WCF一起使用,并且不允许打开泛型类型.

(我假设你已经明白为什么会发生这种情况.如果没有,请阅读我的 overload resolution article并让我知道它是否仍然不清楚.)

如果您使用的是C#4,则可以使用动态类型:

void DoStuff(Foo foo) 
{
    dynamic d = foo;
    DoStuffImpl(d);
}

注意这不仅仅有一个动态参数 – 想法是通过将foo限制为Foo类型或子类,我们总是有一个有效的DoStuffImpl来调用…它只是确定最好的方法在执行时,不是编译时间.

如果你被困在C#4之前,你可以通过双重调度来实现:

class Foo
{
    public virtual void CallStuffImpl(FooImplType x)
    {
        x.DoStuffImpl(this);
    }
}

class Foo<T> : Foo
{
    public override void CallStuffImpl(FooImplType x)
    {
        // Looks like it's redundant, but isn't! "this" is
        // known to be Foo<T> rather than Foo
        x.DoStuffImpl(this);
    }
}

然后:

void DoStuff(Foo foo) 
{
    foo.CallStuffImpl(this); // Let it dispatch appropriately
}
相关文章
相关标签/搜索