使用Using的注意事项
参数传递
C#中有四种参数类型:值类型,Ref参数,Out参数,params参数。默认参数都是以传值方式传递,这意味着方法中的变量会在内存中被分配新的存储空间,并赋值。对于引用类型,这种传值意味着传递的是实例对象在栈中的地址。
void Foo (StringBuilder x)
{
x = null;
} ... StringBuilder y = new StringBuilder();
y.Append ("hello");
Foo (y);
Console.WriteLine (y==null);
代码中的y不会被改变。反之,下面的代码会输出“hello world”。(注意上面赋值的概念,如果变量存在一组子成员变量,现在两个变量都指向了同一片子成员变量,那么子成员变量的变化就会影响到两个变量)
void Foo (StringBuilder x)
{
x.Append (" world");
} ... StringBuilder y = new StringBuilder();
y.Append ("hello");
Foo (y);
Console.WriteLine (y);
如果将参数传递方式修改为Ref,那么上面的y就会被置为null,因为传递的是变量本身而非地址。进入方法的范围时,不会再分配新的存储空间,引用被修改,栈中的地址不再指向已分配的空间。
关于Using
使用Using语句块时,可以再Using语句内定义变量,也可以在其外部定义变量。但是如下这种写法在C#中会报错:Cannot pass 'TheInt' as a ref or out argument because it is a 'using variable'。
public class DisposableInt : IDisposable
{
private int? _Value; public int? MyInt
{
get { return _Value; }
set { _Value = value; }
} public DisposableInt(int InitialValue)
{
_Value = InitialValue;
} public void Dispose()
{
_Value = null;
}
} public class TestAnInt
{
private void AddOne(ref DisposableInt IntVal)
{
IntVal.MyInt++;
} public void TestIt()
{
DisposableInt TheInt;
using (TheInt = new DisposableInt())
{
Console.WriteLine(String.Format("Int Value: {0}", TheInt.MyInt));
AddOne(ref TheInt);
Console.WriteLine(String.Format("Int Value + 1: {0}", TheInt.MyInt));
}
}
}
在Using语句内声明的变量全部是只读变量,这意味着在Using的语句块内不允许更改该对象的引用关系(例如,尝试赋值为null会报错)。因此,如果在此范围内使用ref或者out时会抛出编译器错误。在VB.NET中,不会直接抛出错误,但是会出现TheInt不会被修改的现象。原因在于以上的代码会被编译为(部分代码省略):
public void TestIt()
{
DisposableInt TheInt =new DisposableInt();
DisposableInt TheInt2 = TheInt;
try
{
AddOne(ref TheInt2 );
}
finally
{
}
}
看到一个新的对象代替目标对象进入方法,原有的对象不会被修改。如果在AddOne的范围内出现引用被修改的情况,TheInt和TheInt2的参照关系会被修改。此时,在AddOne之后使用的TheInt实际上已经被编译器自动优化为TheInt2。
为了使用Using,可以讲代码修改为如下,此时TheInt不再是只读变量,就不会遇到此类问题:
DisposableInt theInt = new DisposableInt();
using (theInt)
{
AddOne(ref theInt);
}
使用Using的注意事项的更多相关文章
- jQuery UI resizable使用注意事项、实时等比例拉伸及你不知道的技巧
这篇文章总结的是我在使用resizable插件的过程中,遇到的问题及变通应用的奇思妙想. 一.resizable使用注意事项 以下是我在jsfiddle上写的测试demo:http://jsfiddl ...
- Windows Server 2012 NIC Teaming介绍及注意事项
Windows Server 2012 NIC Teaming介绍及注意事项 转载自:http://www.it165.net/os/html/201303/4799.html Windows Ser ...
- TODO:Golang指针使用注意事项
TODO:Golang指针使用注意事项 先来看简单的例子1: 输出: 1 1 例子2: 输出: 1 3 例子1是使用值传递,Add方法不会做任何改变:例子2是使用指针传递,会改变地址,从而改变地址. ...
- app开发外包注意事项,2017最新资讯
我们见过很多创业者,栽在这app外包上.很多创业者对于app外包这件事情不是特别重视,以为将事情交给app外包公司就完事了,实际上不是的.无论是从选择app外包公司还是签订合同.售后维护等各方面都有许 ...
- favicon.ioc使用以及注意事项
1.效果 2.使用引入方法 2.1 注意事项:(把图标命名为favicon.ico,并且放在根目录下,同时使用Link标签,多重保险) 浏览器默认使用根目录下的favicon.ico 图标(如果你并没 ...
- ORACLE分区表梳理系列(二)- 分区表日常维护及注意事项(红字需要留意)
版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...
- 【原】Masonry+UIScrollView的使用注意事项
[原]Masonry+UIScrollView的使用注意事项 本文转载请注明出处 —— polobymulberry-博客园 1.问题描述 我想实现的使用在一个UIScrollView依次添加三个UI ...
- 《连载 | 物联网框架ServerSuperIO教程》- 5.轮询通讯模式开发及注意事项。附:网友制作的类库说明(CHM)
1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...
- 《连载 | 物联网框架ServerSuperIO教程》- 6.并发通讯模式开发及注意事项
1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...
- 《连载 | 物联网框架ServerSuperIO教程》- 7.自控通讯模式开发及注意事项
1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...
随机推荐
- Tomcat从零开始(十七)——StandardWrapper
第十七课:StandardWrapper 课前复习: 不知道大家是否还有印象,就是在6.7节课说的4种container,粗略的从大到小来说就是engine,host,context,和wrapper ...
- 算法笔记_102:蓝桥杯练习 算法提高 快乐司机(Java)
目录 1问题描述 2 解决方案 1 问题描述 问题描述 "嘟嘟嘟嘟嘟嘟 喇叭响 我是汽车小司机 我是小司机 我为祖国运输忙 运输忙" 这是儿歌“快乐的小司机”.话说现在当司机光 ...
- 你不知道的js技巧
JS进阶 说起这个应该算是老生常谈了吧.所谓的高级,其实就是讲了一些我们平常用不到(或许用了不知道),但是非常实在的东西.算是熟练掌握js的一个必经road吧. 检测函数类型 其实检测函数的类型应该算 ...
- Caused by: java.lang.NoSuchMethodError: javax.persistence.JoinColumn.foreignKey()Ljavax/persistence/
Caused by: Java.lang.NoSuchMethodError: javax.persistence.JoinColumn.foreignKey()Ljavax/persistence/ ...
- Android TCP/IP Socket Test
TCP/IP协议:Transmission Control Protocol/Internet Protocol的简写,中译名为传输控制协议/因特网互联协议,又名网络通讯协议,是Internet最基本 ...
- 自制MVC框架CRUD操作、列表、分页显示插件介绍
这里涉及到的操作都是引用自Stephen.DALService数据层.数据访问层实现方式在后文中我会仔细的说明,先说明一下数据操作集成的插件. 1).InsertAttribute 用于插入记录. 状 ...
- mysql联合查询union
mysql联合查询,对多表进行组合查询 使用 UNION ALL 命令实例 显示所有 使用UNION 过滤重复的 使方法 select * from (SELECT id,name as usenam ...
- Vivado的helloword程序:硬件工程部分
硬件平台:ZedBoard软件平台:vivado2013.3 本示例通过综合.实现,生成比特流,发送到SDK实现.启动vivado并且创建一个项目根据提示操作一步步创建新项目的时候记得选择RTL Pr ...
- oracle分区的名称和值要一致
名称是01,后面的值也必须是02,不能是前面的是1,后面的是02,被这个问题困扰了好久.
- PHP学习笔记(9)文件上传
index.php <!doctype html> <html lang="en"> <head> <meta charset=" ...