English 中文(简体)
2. 具有继承权和一般制约因素的两步方法解决办法
原标题:Two-step method resolution with inheritance and generic constraints

我在利用继承方面的一般限制时,遇到了相当令人惊讶的情况。 我有超载方法<代码>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?

最佳回答

Per OP s request, comment re-posted as answer:

通用课程不是模板。 通用方法一经汇编,其行为针对的是最通用的情况(在本案中为动物)。 这不同于C++风格的排行,每个专业的模板按类型分别汇编。

问题回答

The generic C# method is compiled into a generic IL method. And in IL, you have to explicitly specify which overload you are calling. So there is no simple way how the compiler could have done this. (There is complicated way: run a mini-compiler that chooses the overload at this point dynamically, which is what dynamic does.)

如果你想要这样做的话,一种选择是将<条码>/条码>作为<条码>Animal上的虚拟方法。 另一种选择是使用<代码>动力学。





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签