Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从派生类调用的虚拟方法中的类型_C#_.net_Generics_Virtual Functions - Fatal编程技术网

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

C# 从派生类调用的虚拟方法中的类型,c#,.net,generics,virtual-functions,C#,.net,Generics,Virtual Functions,我发现自己处于这样一种情况:我在基类上有一个方法,该方法调用一个将自身作为参数传递的泛型方法(通过this)。在泛型方法中,类型始终是基类型,即使我从派生类调用该方法也是如此 我需要泛型方法知道它是派生类型而不是基类型 我无法更改通用方法,因为它来自第三方应用程序(http://razorengine.codeplex.com/ -Razor.Parsemethod) 我发现,如果我将该方法定义为一个泛型扩展方法,该方法仅限于从基类继承的类型,那么调用该方法是可行的,但为此目的使用扩展方法似乎很

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

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

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

我发现,如果我将该方法定义为一个泛型扩展方法,该方法仅限于从基类继承的类型,那么调用该方法是可行的,但为此目的使用扩展方法似乎很麻烦(尽管如果这是正确的用法,我很高兴听到这一点)。我想知道的是,是否有一些技巧可以在调用之前将“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);
    }
}

此方法返回静态类型(T)的类型。它应该作为一个整体来实施

public static void WhatType<T>(T obj) 
{ 
    Console.WriteLine(obj.GetType().Name); 
} 
公共静态void WhatType(T obj)
{ 
Console.WriteLine(obj.GetType().Name);
} 
编辑:
我刚刚意识到,您想要的是以这样一种方式操纵A,即通用方法的T发生变化。您可以通过反射或基于a的子类型添加switch语句并显式地将其强制转换为B(或任何类)。当然,这些解决方案都不是好的,因为A将依赖于它的子类和反射。另一个选项是重写每个子类中的GetType()方法,从而将责任转移到子类。

此方法返回静态类型(T)的类型。它应该作为一个整体来实施

public static void WhatType<T>(T obj) 
{ 
    Console.WriteLine(obj.GetType().Name); 
} 
公共静态void WhatType(T obj)
{ 
Console.WriteLine(obj.GetType().Name);
} 
编辑:
我刚刚意识到,您想要的是以这样一种方式操纵A,即通用方法的T发生变化。您可以通过反射或基于a的子类型添加switch语句并显式地将其强制转换为B(或任何类)。当然,这些解决方案都不是好的,因为A将依赖于它的子类和反射。另一个选项是覆盖每个子类中的GetType()方法,从而将责任转移到子类。

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

您需要使用
obj.GetType()
T
是在编译时绑定的,而不是在运行时,因此
typeof(T)
返回编译时类型
T
如果我理解正确,您的问题是
a.GetType()
绑定到
WhatType
,这就是它所知道的一切

因此,您必须让class
A
了解派生类

您可以使用自引用泛型类型执行此操作。比如:

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

class B : A<B> { }

将绑定到
WhatType
,因此将输出
B

如果我理解正确,您的问题是
A.GetType()
绑定到
WhatType
,因为它只知道这些

因此,您必须让class
A
了解派生类

您可以使用自引用泛型类型执行此操作。比如:

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

class B : A<B> { }


将绑定到
WhatType
,因此将输出
B

,如果您的泛型方法关心类型,那么您需要重新评估该方法。嗯,这有点正确-调用的代码是A类!(我知道那没用)我会挖个洞,然后再打给你!您必须在WhatType方法中使用obj.GetType()。此外,GetType是对象上未标记为virtual的方法。请不要试图重写它。如果您的泛型方法关心类型,pass
where T:A
,那么您需要重新评估该方法。嗯,这有点正确-调用代码是类A!(我知道那没用)我会挖个洞,然后再打给你!您必须在WhatType方法中使用obj.GetType()。此外,GetType是对象上未标记为virtual的方法。请不要尝试重写它。typeof需要一个类型。我想你指的是obj.GetType(),它永远不会编译
obj
不是
typeof
的有效参数。它需要一个类型名称。一个注释,而不是对您的答案的批评:这只会起作用,因为您/OP没有将
放置在t:a
中。如果添加该选项,则将使用
A.GetType()
而不是
Object.GetType()
。(
A.GetType
的命名非常糟糕。)是的,事实上它会生成一个警告,因为A.GetType隐藏了Object.GetType(并且没有“new”关键字)。@hvd:我的命名非常糟糕
A.GetType
已更改为
A.myGetType
以区分它。谢谢你的观察。typeof需要一个类型。我想你指的是obj.GetType(),它永远不会编译
obj
不是
typeof
的有效参数。它需要一个类型名称。一个注释,而不是对您的答案的批评:这只会起作用,因为您/OP没有将
放置在t:a
中。如果添加该选项,则将使用
A.GetType()
而不是
Object.GetType()
。(
A.GetType
的命名非常糟糕。)是的,事实上它会生成一个警告,因为A.GetType隐藏了Object.GetType(并且没有“new”关键字)。@hvd:我的命名非常糟糕<密码