调用泛型方法时,指定类型实参常常会显得很多余。为简化工作,c#2编译器被赋予了一定的“智能”,让你在调用方法时,不需要显式声明类型实参。

在深入讨论这个主题之前,必须强调一下:类型推断只适用于泛型方法,不适用于泛型类型。

例子:static List<T> MakeList<T>(T first,T second)

...

List<String> list=MakeList<string>("Line1","Line2");

方法中的每个参数都声明为类型T。即使拿掉方法中调用表达式的<string>部分,也很容易看出在调用方法时,为T使用的类型实参是string。编译器允许将其省略,变成:

List<string> list=MakeList("Line2","Line2");

使用类型推断并非总是意味着增加了可读性。某些情况下会造成读者更难判断你要使用什么类型实参-即使编译器能轻松地判断出来。建议具体情况具体分析。在推断可用的时候,让编译器推断类型实参,多数情况下都没有问题。

注意,编译器之所以能够确定我们要将string作为类型实参使用,是因为对list的赋值也在起作用,它也指定了并且必须指定类型实参。然而,假如编译器推断错了你想要使用的类型实参,你仍可能得到一个编译错误。

编译器为什么会弄错呢?假定实际想用object作为类型实参。我们传递的方法实参仍是有效的,编译器认为我们想要的是string,因为传递的两个参数都是字符串。修改其中一个实参,把它显示转换为object,类型推断就会失败。因为一个方法实参指出T应该是string,另一个指出T应该是一个object。此时,编译器会考虑这种情况并且告知用户将T设为object能满足一切情况,将T设为string则不能。但是,在c#语言规范中,只提供了有限的推断步骤。其基本步骤如下:

1.针对每一个方法实参(普通圆括号中的参数,而不是尖括号中的),都尝试推断出泛型方法的一些类型实参。这一步是相当简单的技术

2.验证步骤一的所有结果都是一致的—换言之,假如从一个方法实参中推断出了某类型参数的类型实参,但根据另外一个类型实参推断出同一个类型参数具有另一个类型实参,则此次方法调用的推断失败。

3.验证泛型方法需要的所有类型实参都已被推断出来,不能让编译器推断一部分,自己显式指定另一部分。要么全部推断,要么全部指定。

类型推断可以结合基于类型参数数量的类型名称重载的想法,来简化泛型类型的使用。

程序清单:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace 类型推断
{
class Program
{
public static List<T> MakeList<T>(T f, T s)
{
List<T> list = new List<T>();
list.Add(f);
list.Add(s);
return list;
}
static void Main(string[] args)
{
List<object> list = MakeList("", (object)"");
foreach (string s in list)
{
Console.WriteLine(s);
}
}
}
}

运行结果:

试验知:类型推断中,如果类型如object,至少要强制转换类型实参中的一个参数,否则推断失败。

c# in depth 之泛型实参的类型推断的更多相关文章

  1. Java 8新特性探究(三)泛型的目标类型推断

    简单理解泛型 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.通俗点将就是"类型的变量".这种类型变量可以用在类.接口和方法 ...

  2. [Effective Modern C++] Item 1. Understand template type deduction - 了解模板类型推断

    条款一 了解模板类型推断 基本情况 首先定义函数模板和函数调用的形式如下,在编译期间,编译器推断T和ParamType的类型,两者基本不相同,因为ParamType常常包含const.引用等修饰符 t ...

  3. Java 10 实战第 1 篇:局部变量类型推断

    现在 Java 9 被遗弃了直接升级到了 Java 10,之前也发过 Java 10 新特性的文章,现在是开始实战 Java 10 的时候了. 今天要实战的是 Java 10 中最重要的特性:局部变量 ...

  4. <T>泛型,广泛的类型

    其实早在1999年的JSR 14规范中就提到了泛型概念,知道jdk5泛型的使用才正式发布,在jdk7后,又对泛型做了优化,泛型的推断. 泛型类 public class Pair<T> { ...

  5. 泛型T的类型获取

    T.getClass()或者T.class都是非法的,因为T是泛型变量. 由于一个类的类型是什么是在编译期处理的,故不能在运行时直接在Base里得到T的实际类型. /** * 可以在service层直 ...

  6. 使用C#反射中的MakeGenericType函数,来为泛型方法和泛型类指定(泛型的)类型

    C#反射中的MakeGenericType函数可以用来指定泛型方法和泛型类的具体类型,方法如下面代码所示这里就不多讲了,详情看下面代码一切就清楚了: using System; using Syste ...

  7. Java泛型-内部原理: 类型擦除以及类型擦除带来的问题

    一:Java泛型的实现方法:类型擦除 大家都知道,Java的泛型是伪泛型,这是因为Java在编译期间,所有的泛型信息都会被擦掉,正确理解泛型概念的首要前提是理解类型擦除.Java的泛型基本上都是在编译 ...

  8. C# 泛型多种参数类型与多重约束 示例

    C# 泛型多种参数类型与多重约束 示例 interface IMyInterface { } class Dictionary<TKey, TVal> where TKey : IComp ...

  9. Gson通过借助TypeToken获取泛型参数的类型的方法

    最近在使用Google的Gson包进行Json和Java对象之间的转化,对于包含泛型的类的序列化和反序列化Gson也提供了很好的支持,感觉有点意思,就花时间研究了一下. 由于Java泛型的实现机制,使 ...

随机推荐

  1. EXT.NET高效开发(三)——使用Chrome浏览器的开发人员工具

    这篇帖子老少皆宜,不分男女,不分种族,不分职业.俗话说:“磨刀不误砍柴工”.掌握一些开发工具的使用,对自己帮助是很大的(无论是用于分析问题,还是提高生产力).本篇就讲述如何利用Chrome浏览器(这里 ...

  2. Python 第八篇:异常处理、Socket语法、SocketServer实现多并发、进程和线程、线程锁、GIL、Event、信号量、进程间通讯

    本节内容: 异常处理.Socket语法.SocketServer实现多并发.进程和线程.线程锁.GIL.Event.信号量.进程间通讯.生产者消费者模型.队列Queue.multiprocess实例 ...

  3. ie6下常见的bug 调整页面兼容性

    ie6下常见的bug 我们布局页面,首先符合标准,如何写一个页面的标准性? 但是ie6等浏览器本身就比较特殊,bug比较多,兵法云,知己知彼百战百胜.我们需要了解ie6的一些常见bug,这样,更好的调 ...

  4. mybatis操作动态表+动态字段+存储过程

    存储过程 statementType="CALLABLE" <!-- 计算金额存储过程--> <update id="getCalcDistributo ...

  5. 基于visual Studio2013解决算法导论之003雇佣问题

     题目 雇用问题 解决代码及点评 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #in ...

  6. 数学之路-python计算实战(15)-机器视觉-滤波去噪(归一化块滤波)

    # -*- coding: utf-8 -*- #code:myhaspl@myhaspl.com #归一化块滤波 import cv2 import numpy as np fn="tes ...

  7. 动态链接库dll的 静态加载 与 动态加载

    dll 两种链接方式  : 动态链接和静态链接(链接亦称加载) 动态链接是指在生成可执行文件时不将所有程序用到的函数链接到一个文件,因为有许多函数在操作系统带的dll文件中,当程序运行时直接从操作系统 ...

  8. 一个带动画效果的颜色选择对话框控件AnimatedColorPickerDialog

    android4.4的日历中选择日程显示颜色的时候有一个颜色选择对话框非常漂亮,模仿他的界面我实现了一个类似的对话框,而且带有动画效果. 代码的实现可讲的地方不多,主要是采用了和AlertDialog ...

  9. NYOJ10,skiing

    skiing 时间限制:3000 ms  |  内存限制:65535 KB 难度:5 描写叙述 Michael喜欢滑雪百这并不奇怪, 由于滑雪的确非常刺激.但是为了获得速度,滑的区域必须向下倾斜,并且 ...

  10. asp.net 中将汉字转换成拼音

    /// <summary> /// 获取汉字的全拼音 /// </summary> /// <param name="x">传汉字的字符串< ...