A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 邵帅 中级黑马   /  2012-12-9 12:18  /  3853 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

为什么c#没有指针,在c语言中使用指针可以 间接引用变量可以作为函数的参数。c#中呢

评分

参与人数 1技术分 +1 收起 理由
宋天琪 + 1

查看全部评分

5 个回复

倒序浏览
C#是没有指针的,如果一定要用,可以用C#中的委托(delegate),效果和函数指针相同学习c#都会惊奇于它的delegate,其实delegate并没有太多神秘的地方,说的通俗点,delegate是类型化了的函数指针,它主要应用于回调。   学习c++的对函数指针都不回陌生,它是一个保存了函数地址的变量,但除了地址,它没有包含任何额外的信息,如参数的个数、参数类型和函数的返回地址等,所以函数指针是非类型安全的。而delegate对回调提供了类型的安全性,从而使我们在处理回调等问题的时候可以更加优美的面向对象的方式来编写代码,并且在CLR的内部对delegate的操作提供了许多支持(如delegate链表),简化了我们常用的操作。   在使用delegate的过程中,首先要定义一个delegate的类型,如:    public delegate void SomeFunction(Object a,int i,...);    note:它是一个类的定义,可以放在任何地方,此类型定义了此delegate所接收的函数的样式:返回void,参数列表...   然后,为了使用,要定义类SomeFunction的一个实例:    public SomeFunction instance;    接着,我们就可以往这个delegate实例中放“符合规范”的函数(可以为实例函数和静态函数)。  instance +=new SomeFunction(someObject.SomeMethod);   其中someObject为某类的一个实例,它的方面SomeMethod符合此委托的规范要求,否则将编译报错。 最后,可以直接调用instance实例来实现对someObject的SomeMethod的回调。  instance(...); ##########################只是从上面的实现中,貌似看不出delegate真正存在的价值,但实际上delegate增加了对链的支持,我们可以象下面这样应用: instance +=new SomeFunction(someObject.SomeMethod); instance +=new SomeFunction(anotherObject.anotherMethod);...然后调用instance(...),可以同时激发所有注册自里面的回调函数。这是怎样实现的,首先要研究delegate内在的结构,在每个delegate里面包括了三个字段: target  ——》指向回调函数所属的对象实例(对于实例方法来言) method ——》指向回调函数 prev ——》指向另外一个delegate 实例通过prev就可以比较方便的实现delegate对链的支持。CLR定义了Delegate.Combine和Delegate.Remove静态方法实现对链表的操作

评分

参与人数 1技术分 +1 收起 理由
宋天琪 + 1

查看全部评分

回复 使用道具 举报
指针是非强类型化的,当使用一个指针的时候,指向的不是一个特定的类型,而仅仅是一块内存区。对这个指针进行位移操作,然后向此位置写入,就可能破坏内存,因此称可以直接操作内存的代码为不安全的(unsafe)。
平时我们使用C#,是在托管平台上,这个平台之所以被称为“托管的”,是因为编程人员不再需要为内存的分配、管理和回收做太多的工作,CLR会在内部管理程序的内存。
但是在某些特殊的情况下,如与本地代码或COM+组件交互的时候,可能需要使用指针来传递参数,这时可以配置C#项目属性,使其“允许不安全的代码”,并在不安全的代码块前用unsafe修饰。这样就可以在C#中使用指针。

评分

参与人数 1技术分 +1 收起 理由
宋天琪 + 1

查看全部评分

回复 使用道具 举报
C#的代码经过编译后产生的各种对象大多都是受.Net框架管理的托管代码。与C不同的是它的内存管理是由.Net框架提供,而不像C要自己管理。

评分

参与人数 1技术分 +1 收起 理由
宋天琪 + 1

查看全部评分

回复 使用道具 举报
接上面的,实际上C#中的引用就是一个指针,它的内容就是它所引用对象的地址。只不过在没有特殊声明的情况下,C#的引用属于.Net托管的安全的指针。而且C#的引用语法不允许直接访问引用所包含的变量地址,这样就失去了C++中直接对指针操作的灵活性和技巧。C#的引用主要提供了易用和安全的方式访问内存,能够防止用户无意中执行某些破坏内存内容的操作。但如果确实需要使用指针直接访问内存,那么这段代码将被视作不安全代码,需要特别标注。在方法或类型前面加unsafe关键字。
回复 使用道具 举报
C#开unsafe是可以用指针的...托管代码可以用Delegate

评分

参与人数 1技术分 +1 收起 理由
宋天琪 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马