关闭

C#泛型方法的类型推断

发表于:2013-3-21 10:09

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:CYJB    来源:51Testing软件测试网采编

  这个问题是我在测试上一篇随笔C#使用Binder类自定义反射》中的类时发现的,当时为了能够让 PowerBinder 支持泛型方法绑定,完成了一些简单的类型推断工作,但是它只能支持直接使用泛型参数 T 作为参数类型,对于 T[],IList<T> 这种复杂一些的情况是不能处理的。

  或者举个复杂点的例子,对于下面的泛型方法定义:

void Method<T>(IList<T> a, params T[] args);

  再给出参数类型为:

  1. typeof(IList<int>), typeof(int[]) } 
  2. typeof(IList<int[]>), typeof(int[]) } 
  3. typeof(IList<int[]>), typeof(int[][]) }

  我希望能够正确的推断出 T 的类型分别为 int、int[] 和 int[]。

  后来参考了《CSharp Language Specification》v5.0 中 7.5.2 类型推断 一节,规范中给出了 C# 中进行类型推断的两阶段算法,算法分为两阶段主要是为了支持实参表达式和匿名函数的推断,而我的需求则要简单很多,只要支持普通的参数就可以了。又参考了 7.5.2.13 方法组转换的类型推断 一节,最终得到了下面的简化算法。

  首先对几个名词进行区分:类型形参、类型实参、方法形参和方法实参。

  对于泛型方法定义 void Method<T>(T a),其中的 T 是类型形参,T a 是方法形参。

  对于相应的封闭泛型方法的调用 Method<int>(10),其中的 int 就是类型实参,10 就是方法实参。

  泛型方法的类型推断,从形式上来定义,就是对给定泛型方法 Tr M<X1, …, Xn>(T1 x1, …, Tm xm),其中 Tr 是返回值,X1, …, Xn 是类型形参,T1, …, Tm 是方法形参,和一个委托类型 D(U1 x1, …, Um xm),找到一组类型实参 S1, …, Sn,使表达式 M<S1, …, Sn> 与 D 兼容(D 可由 M<S1, …, Sn> 隐式转换而来)。

  该算法首先认为所有 Xi 均未固定(即没有预设值),并从 D 的每个实参类型 Ui 到 M 的对应形参类型 Ti 进行下限推断(前提是 Ti 包含类型形参,即 ContainsGenericParameters == true),但是如果 xi 为 ref 或 out 形参,则从 Ui 到 Ti 进行精确推断。如果没有为任何 Xi 找到界限,则类型推断将失败。否则,所有将 Xi 均固定到对应的 Si,它们是类型推断的结果。下面给出详细的推断算法,这里的算法经过了我的修改,与原规范并不完全相同。

  1、下限推断

  这里的下限推断指的是对于给定的实参类型 U,找到合适的形参类型 V,使得 V.IsImplicitFrom(U)。

  按如下所述从类型 U 到类型 V 进行下限推断:

  1)如果 V 是 Xi 之一,则将 U 添加到 Xi 的下限界限集中。

  2)否则,如果 V 为 V1?  类型,而 U 为 U1? 类型,则从 U1 到 V1 进行下限推断。

  3)否则,如果 V 是数组类型 V1[…],U 是具有相同秩的数组类型 U1[…],或者 V 是一个 IEnumerable<V1>、ICollection<V1> 或 IList<V1>,U 是一维数组类型 U1[],则从 U1 到 V1 进行下限推断。

  4)否则,如果 V 是构造类、结构、接口或委托类型 C<V1…Vk>,并且存在唯一类型 C<U1…Uk> ,使 U 等于、(直接或间接)继承自或者(直接或间接)实现 C<U1…Uk>(“唯一性”限制表示对于 interface C<T>{} class U: C<X>, C<Y>{},不进行从 U 到 C<T>  的推断,因为 U1 可以是 X 或 Y。),则从每个 Ui 到对应的 Vi 进行推断,推断依赖于 C 的第 i 个类型参数:

  ● 如果该参数是协变的,则进行下限推断。

  ● 如果该参数是逆变的,则进行上限推断。

  ● 如果该参数是固定的,则进行精确推断。

  5)否则,不进行任何推断。

21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号