我在利用继承方面的一般限制时,遇到了相当令人惊讶的情况。 我有超载方法<代码>Foo,与参数不同——无论是基础还是衍生的类别。 在这两种情况下,通常都会将案件转至超载方法的第二层楼――Bar
。
When I call Foo
with base class instance, Bar
overload for the base class is called. When I call Foo
with derived class instance, Bar
overload for the derived class is called. This is clear and expected.
但当我试图合并<代码>时。 Foo methods into one GenericFoo
that use generals and restrictions, methods are reflectedly - T is disabilities resolution, but only base-class overload of Bar
.
public class Animal { }
public class Cat : Animal { }
public class AnimalProcessor
{
public static void Foo(Animal obj)
{
Console.WriteLine("Foo(Animal)");
Bar(obj);
}
public static void Foo(Cat obj)
{
Console.WriteLine("Foo(Cat)");
Bar(obj);
}
// new generic method to replace the two above
public static void GenericFoo<T>(T obj)
where T : Animal
{
Console.WriteLine("Foo(generic)");
Bar(obj);
}
public static void Bar(Animal obj)
{
Console.WriteLine("Bar(Animal)");
}
public static void Bar(Cat obj)
{
Console.WriteLine("Bar(Cat)");
}
}
测试代码——非遗传性旧方法的头两例,新通用方法的两例。
Console.WriteLine("Animal()");
AnimalProcessor.Foo(new Animal());
Console.WriteLine();
Console.WriteLine("Cat()");
AnimalProcessor.Foo(new Cat());
Console.WriteLine();
Console.WriteLine("Animal()");
AnimalProcessor.GenericFoo(new Animal());
Console.WriteLine();
Console.WriteLine("Cat()");
AnimalProcessor.GenericFoo(new Cat());
Console.ReadLine();
And the result - note the difference in type resolved in Bar
:
Animal()
Foo(Animal)
Bar(Animal)
Cat()
Foo(Cat)
Bar(Cat)
Animal()
Foo(generic)
Bar(Animal)
Cat()
Foo(generic)
Bar(Animal)
It looks like the compiler binds all calls from GenericFoo
to the least specific overload, even if all more specific-typed calls are known at compile time. Why is that, what is the reason for such behaviour? Which part of specs defines this?