17.C#类型判断和重载决策(九章9.4)
今天来结束第九章,聊下我们经常忽略,但是编译器会帮我们完成的"类型判断和重载决策",理解编译器如何帮我们完成,相信在写代码时会更明确,避免一些编译出错,排查的问题,让我们开发更给力。
我们知道隐式类型的数组以及将方法组转换为委托类型都需要类型推断,但将方法组作为其它方法的参数进行转换时,会显得极其复杂,我们由浅入深,一步一步来看,编译器是如何帮我们做的一些推断。
//定义一个泛型方法,参数分别为TInput类型和一个Func<TInput, TResult>类型的委托
public static TResult Get<TInput, TResult>(TInput input, Func<TInput, TResult> func)
{
return func(input);
}
static void Main(string[] args)
{
var a = Get("", x => int.Parse(x));
//第一个参数是字符串,所以可以推断TInput类型有到string类型的隐式转换
//则方法签名为:public static TResult Get<string, TResult>(string input, Func<string, TResult> func)
//第二个参数是一个Lambda表达式,根据返回的类型是一个int,所以可以推断TResult类型有到int类型的隐式转换
//则方法签名为:public static int Get<string, int>(string input, Func<string, int> func)
//根据上述的步骤,我们推断出了TInput和TResult类型
}
返回类型集合
从上述代码中,可以看到TResult类型是由Lambda表达式的返回值类型来推断的,那如果我有多个返回类型又是一种什么情况呢?请看下面的代码。
var b = Get(, delegate (int x) {
if (x == )
{
return "";
}
else
{
return new object();
}
});
//由上可以推断出TInput类型有到int类型的隐式转换,则TInput为int
//而返回类型有两个,一个是string类型,一个是object类型,但是string类型有到object类型的隐式转换,则TResult为object类型
//编译器帮我们把所有的返回类型放入一个集合,对集合中的类型进行判断,判断是否有一个类型是可由剩余其它类型隐式转换可得,则把这个类型作为返回值的类型
如何选择正确的重载
如果重载具有二义性,那编译肯定是过不了的,要么强制转换某个参数以符合某个方法的签名,或者修改重载方法。从参数或者返回类型考虑,请参照下面一条:
从任何类型"转换成它本身"被认为好于"转换成其它类型",如
static void Debug0(int x) { }
static void Debug0(double x) { }
Debug0(); //static void Debug0(int x)
Debug0(5.0); //static void Debug0(double x)
//int有到double的隐式转换,所以存在二义性,但根据int=>int是好于int=>double的,所以选择使用static void Debug0(int x)
同理于返回类型,作用于委托或者Lambda表达式,如
static int Debug1(Func<int> func) {
return func();
}
static double Debug1(Func<double> func)
{
return func();
}
Debug1(() => 1.1);
Debug1(delegate () { return 1.1; });
//根据Lambda表达式和匿名方法,Debug1(() => 1.1)和Debug1(delegate () { return 1.1; })返回的类型是double类型,则Lambda表达式和匿名方法转换成Func<double>类型的实例,调用的则是static double Debug1(Func<double> func)
Debug1(() => );
Debug1(delegate () { return ; });
//根据Lambda表达式和匿名方法,Debug1(() => 1)和Debug1(delegate () { return 1; })返回的类型是int类型,则Lambda表达式和匿名方法转换成Func<int>类型的实例,调用的则是static double Debug1(Func<int> func)
请斧正。
17.C#类型判断和重载决策(九章9.4)的更多相关文章
- C#与Java对比学习:类型判断、类与接口继承、代码规范与编码习惯、常量定义
类型判断符号: C#:object a; if(a is int) { } 用 is 符号判断 Java:object a; if(a instanceof Integer) { } 用 inst ...
- 第17课 类型萃取(1)_基本的type_traits
1. type_traits类型萃取 (1)type_traits通过定义一些结构体或类,并利用模板类特化和偏特化的能力,给类型赋予一些特性,这些特性根据类型的不同而异.在程序设计中可以使用这些tra ...
- python的数据结构分类,以及数字的处理函数,类型判断
python的数据结构分类: 数值型 int:python3中都是长整形,没有大小限制,受限内存区域的大小 float:只有双精度型 complex:实数和虚数部分都是浮点型,1+1.2J bool: ...
- JS类型判断typeof PK {}.toString.call(obj)
参考链接:https://www.talkingcoder.com/article/6333557442705696719 先看typeof <!doctype html> <htm ...
- Lambda03 方法引用、类型判断、变量引用
1 方法引用 1.1 方法引用的好处 方法引用结合 Lambda 可以引用已存在的方法,省略很多编码,而且可读性更强,它可以自动装配参数与返回值. 在编写lambda表达式的时候可以通过方法引用的方式 ...
- Swift4 类与继承, 类型转换, 类型判断
创建: 2018/03/05 完成: 2018/03/07 更新: 2018/03/09 完善标题 [Swift4 类与继承, 类型转换] -> [Swift4 类与继承, 类型转换与判断] 补 ...
- C#保留2位小数几种场景总结 游标遍历所有数据库循环执行修改数据库的sql命令 原生js轮盘抽奖实例分析(幸运大转盘抽奖) javascript中的typeof和类型判断
C#保留2位小数几种场景总结 场景1: C#保留2位小数,.ToString("f2")确实可以,但是如果这个数字本来就小数点后面三位比如1.253,那么转化之后就会变成1.2 ...
- 【C/C++开发】C++11的模板类型判断——std::is_same和std::decay
C++11的模板类型判断--std::is_same和std::decay 问题提出:有一个模板函数,函数在处理int型和double型时需要进行特殊的处理,那么怎么在编译期知道传入的参数的数据类型是 ...
- 20190908 On Java8 第十九章 类型信息
第十九章 类型信息 RTTI(RunTime Type Information,运行时类型信息)能够在程序运行时发现和使用类型信息. Java 主要有两种方式在运行时识别对象和类信息: "传 ...
随机推荐
- java String部分源码解析
String类型的成员变量 /** String的属性值 */ private final char value[]; /** The offset is the first index of the ...
- linux硬链接与软链接
在linux操作系统中的文件数据除了实际的内容外,还会含有文件权限(rwx)与文件属性(owner,group,other等),文件系统通常会将这两部分的数据存放在不同的区块,文件权限与文件属性放置在 ...
- python module getopt usage
import getopt import sys def usage(): print 'this is a usage.' def main(): try: print sys.argv #sys. ...
- 搭建appium的android环境
首先需要准备: 1.jdk(步骤不再啰嗦) 2.android SDK,下载地址:http://developer.android.com/sdk/index.html,下载sdk tools,可能需 ...
- Windows路由表详解
对于路由器的路由表,大部分网管朋友都很熟悉,但是对于windows的路由表,可能了解的人就相对少一些.今天我们就一起来看看windows路由表. 一. windows路由表条目解释 1. 使用ip ...
- 如何实现ZBrush中的Alt和Shift键的快速运用
ZBrush是一个数字雕刻和绘画软件,它以强大的功能和直观的工作流程彻底改变了整个三维雕刻行业.在一个简洁的界面中,ZBrush®为当代数字艺术家提供了世界上最先进的工具.利用快捷键能使操作更快捷高效 ...
- [转载]ExtJs4 笔记(8) Ext.slider 滚轴控件、 Ext.ProgressBar 进度条控件、 Ext.Editor 编辑控件
作者:李盼(Lipan)出处:[Lipan] (http://www.cnblogs.com/lipan/)版权声明:本文的版权归作者与博客园共有.转载时须注明本文的详细链接,否则作者将保留追究其法律 ...
- 2014 Super Training #2 C Robotruck --单调队列优化DP
原题: UVA 1169 http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show ...
- C# 程序性能提升篇-1、装箱和拆箱,枚举的ToString浅析
前景提要: 编写程序时,也许你不经意间,就不知不觉的使程序代码,发生了装箱和拆箱,从而降低了效率,不要说就发生那么一次两次,如果说是程序中发生了循环.网络程序(不断请求处理的)等这些时候,减少装箱和拆 ...
- 运维工作中常用到的几个rsync同步命令
作为一个运维工程师,经常可能会面对几十台.几百台甚至上千台服务器,除了批量操作外,环境同步.数据同步也是必不可少的技能.说到“同步”,不得不提的利器就是rsync. 下面结合本人近几年运维工作中对这一 ...