如何将泛型类型传递给泛型方法?

时间:2016-04-01 13:33:42

标签: c# generics

为什么我不能拨打 $res = $client->request('POST', 'http://site.flg360.co.uk/api/APILeadCreateUpdate.php', [ $xml, ]); echo($res->getStatusCode()); die();

SomeGenericMethod<SomeGenericType<>>

4 个答案:

答案 0 :(得分:7)

编译器需要专门的类型来专门化泛型方法,Generic<>不是专门的,它是通用的。因此,虽然Generic<>是一种类型,但它并不专门用于泛型方法的专门化。

答案 1 :(得分:2)

  

为什么我不能拨打SomeGenericMethod<SomeGenericType<>>

最简单的答案是:因为language specification这样说:

  

4.4构造类型

     

泛型类型声明本身表示一种未绑定的泛型类型,它通过应用类型参数用作形成许多不同类型的“蓝图”。类型参数写在尖括号(&lt;和&gt;)之后,紧跟在泛型类型的名称之后。包含至少一个类型参数的类型称为构造类型。构造类型可以在可以出现类型名称的语言中的大多数地方使用。 未绑定的泛型类型只能在typeof-expression(第7.6.11节)中使用。

  

4.4.3绑定和未绑定类型

     

术语未绑定类型是指非泛型类型或未绑定泛型类型。术语绑定类型是指非泛型类型或构造类型。   未绑定类型是指由类型声明声明的实体。未绑定的泛型类型本身不是类型,不能用作变量,参数或返回值的类型,也不能用作基类型。 可以引用未绑定泛型类型的唯一构造是typeof表达式(第7.6.11节)。

为什么C#规范会这样说?因为CLI spec也决定了这一点:

  

II.9.4实例化通用类型

     

...

     

CLI不支持泛型类型的部分实例化。并且通用类型不应在元数据签名blob中的任何位置显示为未实例化。

好的,现在让我们停止使用法律术语。您问题的实际答案是:

当您第一次调用SomeMethod<SomeType>()时,CLR将调用JIT编译器,该编译器将读取SomeMethod<T>,替换T创建 new代表SomeMethod<SomeType>的可执行代码。

当您致电SomeMethod<SomeOtherType>()时,需要重复此过程,系统会为SomeMethod<SomeOtherType>生成全新的代码。

您不能仅为Generic<>这样的未绑定泛型类型创建有效代码。在一般情况下,JIT无法知道在不知道T的情况下生成什么代码表示。

  • 如果Tstring并且您的方法声明了类型为T的局部变量,则JIT将分配堆栈空间或使用具有本机指针大小的寄存器。 / LI>
  • 如果TGuid,则JIT必须为固定的128位值分配堆栈空间。如果它不知道T将会是什么,它就无法生成代码。

因此,一般,您无法为未绑定类型生成可执行代码。为什么你可以可以为你提供的代码片段做这件事,这需要特殊的套管,如果你在{{1}中添加T本地代码,你的调用代码就会停止工作} 方法。由于泛型必须可以跨程序集重用,因此调用代码不能假设有关被调用方法的任何内容。

答案 2 :(得分:0)

PrintType<Generic<YOU NEED TO PUT TYPE HERE>>();

答案 3 :(得分:-2)

尝试这样的事情:

public class Generic<T>
{
    public void PrintType(T param)
    {
        Console.WriteLine(param.GetType().Name);
    }
}