调用 C# 基础 class 扩展而不是派生 class 的扩展

C# base class extension is called instead of the one for a derived class

我有 class A,它是 B 的基础 class。以及两种类型的扩展。然后,如果我从泛型函数调用扩展(即使是 B 类型的对象),它仍然会调用基础 class

的扩展
void Main()
{
    var b = new B();
    
    GenericClass.SomeGenericFunction<B>(b);
}

public class A
{
    public void fooA()
    {
        Console.WriteLine("A");
    }
};

public class B : A
{
    public void fooB()
    {
        Console.WriteLine("B");
    }
};

public static class Extension {
    public static void SomeMethod(this A a)
    {
        a.fooA();
    }
    
    public static void SomeMethod(this B b)
    {
        b.fooB();
    }
};

public static class GenericClass {
    public static void SomeGenericFunction<T>(T someObject) where T : A, new()
    {
        someObject.SomeMethod();
    }
};

问题基本上是为什么结果是?

A

引用类型的通用方法共享所有引用类型的实现,因此编译器将在编译期间仅解析一次 SomeMethod - 对于层次结构中的“最高”class - A。您可以通过使 SomeMethod 成为 A 层次结构的虚拟实例方法或在通用函数中使用类型检查来更改 A(和 B)来解决此问题:

public static class GenericClass 
{
    public static void SomeGenericFunction<T>(T someObject) where T : A, new()
    {
        switch (someObject)
        {
            case B b:
                b.SomeMethod();
                break;
            case A:
            default:
                someObject.SomeMethod();
                break;
        }
    }
}

或潜入反思。

试试这个

public class A
{
    public virtual void foo()
    {
        Console.WriteLine("A");
    }
};

public class B : A
{
    public override void foo()
    {
        Console.WriteLine("B");
    }
};

public static class Extension
{
    public static void SomeMethod(this A a)
    {
        a.foo();
    }

    public static void SomeMethod(this B b)
    {
        b.foo();
    }
};

public static class GenericClass
{
    public static void SomeGenericFunction<T>(T someObject) where T : A, new()
    {
        someObject.SomeMethod();
    }
};

测试

   var b = new B();

    GenericClass.SomeGenericFunction<B>(b);

结果

B

如果您需要保留您的 类,您也可以使用此代码。它更容易扩展和维护。我只是不明白为什么使用 GenericClass 还需要扩展?也许像 C 波纹管一样更容易使用?或者只是使用扩展。好像他们在互相重复。

public static class GenericClass 
{
    public static void SomeGenericFunction(B someObject) 
    {
        someObject.SomeMethod();
    }
public static void SomeGenericFunction(C someObject) 
    {
        someObject.fooC();
    }
    public static void SomeGenericFunction<T>(T someObject) where T : A, new()
    {
        someObject.SomeMethod();
    }
}