类型在从派生类调用的虚拟方法中

本文关键字:虚拟 方法 调用 派生 类型 | 更新日期: 2023-09-27 18:32:59

我发现自己的情况是,我在基类上有一个方法,该方法调用一个泛型方法,将自身作为参数传递(通过this(。在泛型方法中,类型始终是基类型,即使我从派生类调用该方法也是如此。

我需要泛型方法知道它是派生类型而不是基类型。

我无法更改通用方法,因为它来自第三方应用程序(http://razorengine.codeplex.com/- Razor.Parse方法(。

我发现,如果我将该方法定义为仅限于从我的基类继承的类型的一般扩展方法,那么调用它就可以了,但为此目的使用扩展方法似乎很混乱(尽管如果这是正确的用法,我很高兴听到(。我想知道我是否可以使用一些技巧,在调用之前将"this"转换为派生对象的类型(可能仍然使用泛型(。

我在下面包含一个简化的程序,它应该是自包含的(为了个人的方便,我在 LINQPad 中运行它(。本质上,我想要一个在A上定义的方法,当在B实例上调用该方法时,将调用Test.WhatType并输出"B"。

我希望这是有道理的。

void Main()
{
    var bar = new B();
    bar.myGetType();
    bar.ExtGetType();
}
class A
{
    public virtual void myGetType()
    {
        Test.WhatType(this);
        this.ExtGetType();
    }
}
class B : A {}
static class ext
{
    public static void ExtGetType<T>(this T obj) where T : A
    {
        Test.WhatType(obj);
    }
}
class Test
{
    public static void WhatType<T>(T obj)
    {
        Console.WriteLine(typeof(T).Name);
    }
}

编辑:将方法名称更改为A.myGetType(),因为我什至没有注意到我不小心超载了。

注意:运行此代码输出:

A
A
B

类型在从派生类调用的虚拟方法中

你需要使用 obj.GetType() . T在编译时绑定,而不是运行时绑定,因此typeof(T)返回编译时类型 T

如果我

理解正确,你的问题是A.GetType()绑定到WhatType<A>,因为这就是它所知道的全部。

因此,您必须让类A知道派生类。

可以使用自引用泛型类型执行此操作。像这样:

class A<T> where T : A<T>
{
    public virtual void GetType()
    {
        Test.WhatType<T>( (T) this );
    }
}
class B : A<B> { }

然后:

new B().GetType();

将绑定到WhatType<B>因此将输出B

此方法返回静态类型 (T( 的类型。它应该实现为

public static void WhatType<T>(T obj) 
{ 
    Console.WriteLine(obj.GetType().Name); 
} 

编辑:我刚刚意识到你想要的是以一种通用方法的 T 发生变化的方式操作 A。您可以通过反射或添加基于 A 的子类型的 switch 语句并将其显式转换为 B(或任何类(来执行此操作。当然,这些解决方案都不是好的,因为 A 会依赖于它的子类,并且反射显然是 sux。另一种选择是覆盖每个子类中的 GetType(( 方法,从而将责任转移到子类。