前言

继续整理误区系列,可能会对刚入门的新手有些帮助,然后希望有错误的地方可以指出。

正文

关于泛型方法的确定

class Person<T>
{
public void add(T a)
{
}
}

那么请问这个add 是否是泛型方法。

初学者可能认为有泛型参数的就是泛型,其实不是的。

这个是为什么呢?其实是这样子的,当泛型类型确认的时候,那么add 定义的时候就已经确定了类型。

比如说Person,那么这个T就是string,Person 是泛型,但是Person不是。

当T确定是string的时候,在方法申明的时候就已经是string了,而不存在泛型这个概念。

所有泛型的开销没有我们想象的这么大,在应用中,甚至使用泛型效率更高,不是说泛型是优化,而是泛型帮我们避免了太多装箱和拆箱操作。

比如说以前的ArrayList,当我们把int 存进去,是装箱,使用int又是拆箱。

泛型方法是这样的:

class Person<T>
{
public void add<Q>(T a,Q b)
{
}
}

在每次调用add的时候都必须确认Q的类型。

可空类型是引用类型?

因为可空类型是可以为空的,那么初学者可能就认为可空类型是引用类型了。

其实可空类型是值类型,这个是为什么?看下其中的原理。

说是可空值类型,里面包含着一个判断位。

这个是什么意思呢,比如说一个字节表示0-255,那么会多分配一位去判断这个字节是否为空。

就是多一个位去判断是否为空。

那么这样我们是不是就可以随便使用呢?

从内存和cpu的角度来说,一个可空会增加一位,会增加内存消耗。同样每次使用的时候都要判断是否为null,会增加cpu负担。

既然是值类型,那么就存在装箱和拆箱过程,那么这个过程有什么不同吗?

装箱时检查是否为null,如果为null则直接返回null,如果不是null则获取值进行装箱。

拆箱时如果不是null,则返回值,否则返回null。

所以在c# 不能把null 看做是某个具体的地址,0x00之类的,更多的是一个概念。

那么问题来了,为什么int 不能为空?或者值类型不能为空?

很多回答是这样子的,值变量的本身是具体的值。那么难道引用类型不是指的具体的地址吗?

个人觉得是这样子的,int 类型的定义就规定了多少位为(应用程序如果判断是int的),具有某种稳定的结构,如果破坏这种结构,那么就不是int了。所以int类型不能为null,这是int类型的定义。

事件是一种特殊的委托?

个人认为这句话存在很大的问题,是一个概念性问题。

比如说,我们说正方形是一种特殊的长方形。

为什么可以这么说呢?来看一下长方形的定义。

长方形是有一个角是直角的平行四边形。

长方形的性质为:两条对角线相等;两条对角线互相平分;两组对边分别平行;

两组对边分别相等;四个角都是直角;有2条对称轴(正方形有4条);

具有不稳定性(易变形);长方形对角线长的平方为两边长平方的和;顺次连接矩形各边中点得到的四边形是菱形。

从这个定义中,我们得知长方形包含了正方形,因为其中长方形并没有定义长和宽不相等啊。

同样正方形本身就是长方形,只是说正方形在长方形的条件下,增加了其他条件。

综上所述,是可以这么说的。

但是事件是一种特殊的委托,是真的不能这么讲,因为是两种完全不同的概念。

什么是事件?

1.事件的拥有者

2.事件成员(事件的本身)

3.事件响应者

4.事件处理器:本质上是一种回调方法

5.事件的订阅:谁响应谁订阅

什么是委托?

委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。

你会发现这是两种是不同的概念。那么是如何产生这种误解的呢?

看到网上大量流传着:public delegate void EventHandler(object sender, EventArgs e);

这只是说明委托是事件的一种驱动方式,如果把事件认为是一种委托就比较狭隘了,因为有些业务用到事件,如果想到事件就想到委托,就会陷入到僵局中,这样没有去从新定义更复杂的事件。

可能这样不好理解,举一个例子,比如说观察者模式,c# 中委托作为观察者例子,但是观察者和委托没有任何直接关系,难道没有委托,观察者就不存在?

具体可见观察者:https://www.cnblogs.com/aoximin/p/13726813.html

datetime 是引用类型?

初学者看到datetime 有方法就认为是引用类型,因为值类型都更加简单,没有那么多可操作的方法,然而datetime的确是值类型。

这里涉及到一个问题,那么就是值类型的定义上,值类型的判断不是说存在的位置,也不是说值类型没有方法,而是指这种类型的值是否具有一个稳定的结构(大小等)。

那么是否值类型比引用类型性能更好呢?

这个肯定不是的。值类型(栈上)的优点在于,不用垃圾回收,不会因为类型标识而产生开销,也不用解引用。存储在堆上的值类型,直接和对象一起回收。

这里解释一下,为什么不用垃圾回收,因为如果int 类型不可引用,表示在运行系统中没有其地址了。再举个例子,就是我们磁盘清空了,格式化了,数据还在,只是在它的运行系统中不认为其存在有效数据。

所以说为什么值类型在创建的时候要清空分配的地址,是在使用的时候抹除的。

引用类型的有点在于传递,因为引用类型不用复制整个地址块,只需要复制堆上对象的指定位置,32位是4个字节,64是8个字节。

对象在c# 中默认传递是引用传递的

这个问题涉及于,这样一个场景。

void doSomething(Student student)
{
}
doSomething(a);

那么问题是student是如何赋值的过程?是将这个a对象赋值给他吗?

这个问题就是student这个变量存在堆上还是栈上了?student的值本身是地址,而地址是固定的类型(32位4个字节,64位8个字节),其实是值类型。

传递过程是将a的值传递给student,之所以叫做引用类型,是他们的值指向的位置。

那么问题来了:

void doSomething(Student student)
{
}
doSomething(null);

那么student是否有值?也是有值的,指向就是null,在引用类型中它本身就是一个对象。

未完,续。

c# 误区系列(二)的更多相关文章

  1. 前端构建大法 Gulp 系列 (二):为什么选择gulp

    系列目录 前端构建大法 Gulp 系列 (一):为什么需要前端构建 前端构建大法 Gulp 系列 (二):为什么选择gulp 前端构建大法 Gulp 系列 (三):gulp的4个API 让你成为gul ...

  2. WPF入门教程系列二十三——DataGrid示例(三)

    DataGrid的选择模式 默认情况下,DataGrid 的选择模式为“全行选择”,并且可以同时选择多行(如下图所示),我们可以通过SelectionMode 和SelectionUnit 属性来修改 ...

  3. Web 开发人员和设计师必读文章推荐【系列二十九】

    <Web 前端开发精华文章推荐>2014年第8期(总第29期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...

  4. Web 前端开发人员和设计师必读文章推荐【系列二十八】

    <Web 前端开发精华文章推荐>2014年第7期(总第28期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...

  5. Web 开发精华文章集锦(jQuery、HTML5、CSS3)【系列二十七】

    <Web 前端开发精华文章推荐>2014年第6期(总第27期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...

  6. Web 前端开发人员和设计师必读精华文章【系列二十六】

    <Web 前端开发精华文章推荐>2014年第5期(总第26期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...

  7. Web 前端开发精华文章推荐(HTML5、CSS3、jQuery)【系列二十三】

    <Web 前端开发精华文章推荐>2014年第2期(总第23期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...

  8. Web 前端开发精华文章推荐(HTML5、CSS3、jQuery)【系列二十二】

    <Web 前端开发精华文章推荐>2014年第一期(总第二十二期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML ...

  9. 【圣诞特献】Web 前端开发精华文章推荐【系列二十一】

    <Web 前端开发精华文章推荐>2013年第九期(总第二十一期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各种增强网站用户体验的 jQuery 插件,展示前沿的 HTML5 和  ...

随机推荐

  1. 学习 | canvas实现图片懒加载 && 下滑底部加载

    用canvas实现图片的懒加载并且下滑到据底部60px的时候再次加载数据,模仿UC浏览器的新闻加载. 完整代码:https://github.com/dirkhe1051931999/writeBlo ...

  2. 安装Linux的CentOS操作系统 - 初学者系列 - 学习者系列文章

    Linux系统对于一些熟悉Windows操作系统的用户来说可能比较陌生,但是它也是一种多用户.多任务的操作系统,现在也发展成为了多种版本的操作系统了.如果想对该系统进行学习,请下载这个学习文档:htt ...

  3. 重磅来袭 Vue 3.0 One Piece 正式发布

    代号为One Piece 的Vue3.0 在9月19日凌晨正式发布!! 此次vue3.0 为用户提供了全新的 composition-api 以及更小的包大小,和更好的 TypeScript 支持. ...

  4. Mybatis接口Mapper内的方法为啥不能重载吗?

    动态代理的功能:通过拦截器方法回调,对目标target方法进行增强. 言外之意就是为了增强目标target方法.上面这句话没错,但也不要认为它就是真理,殊不知,动态代理还有投鞭断流的霸权,连目标tar ...

  5. kafka学习(四)kafka安装与命令行调用

    文章更新时间:2020/06/07 一.安装JDK 过程就不过多介绍了... 二.安装Zookeeper 安装过程可以参考此处~ 三.安装并配置kafka Kafka下载地址  http://kafk ...

  6. python类,魔术方法等学习&&部分ssti常见操作知识点复习加深

    python类学习&&部分ssti常见操作知识点复习加深 在做ssti的模块注入的时候经常觉得自己python基础的薄弱,来学习一下,其实还是要多练习多背. 在python中所有类默认 ...

  7. 一文了解Zookeeper

    Zookeeper是Apache开源的一个分布式框架,它主要为分布式应用提供协调服务. Zookeeper主要负责存储和管理大家都关心的数据,一旦这些数据的状态发生变化,Zookeeper就会通知那些 ...

  8. pytest封神之路第零步 快速入门

    背景:本文是在系列第五篇发表后的补充篇章,第一篇介绍了tep,可能对不熟悉pytest的朋友不够友好,特意补充入门篇,帮大家快速了解如何动手写pytest.如果你是从这篇文章第一次阅读,那么请忽略以上 ...

  9. java.lang.UnsupportedOperationException: A TupleBackedMap cannot be modified.解决以及探究

    java.lang.UnsupportedOperationException: A TupleBackedMap cannot be modified. at org.springframework ...

  10. git将本地仓库中的文件上传到远程仓库

    现在我们开始创建本地git仓库(版本库又叫仓库) (本地仓库:$ git init之后的目录): 1.任意地方新建文件夹aaa,右击git bash here, 2.弹出一个对话框, 3. 首先配置你 ...