为什么我不能拨打 $res = $client->request('POST',
'http://site.flg360.co.uk/api/APILeadCreateUpdate.php', [
$xml,
]);
echo($res->getStatusCode());
die();
?
SomeGenericMethod<SomeGenericType<>>
答案 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
的情况下生成什么代码表示。
T
是string
并且您的方法声明了类型为T
的局部变量,则JIT将分配堆栈空间或使用具有本机指针大小的寄存器。 / LI>
T
是Guid
,则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);
}
}