使用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中server.xml配置详解(转载)(三)
转载自:https://www.cnblogs.com/starhu/p/5599773.html 一. <Engine>元素 每个Service元素只能有一个Engine元素.处理在同 ...
- vue - for遍历数组
注释上,也很清楚了哈. 1. item是循环名字,items是循环的数组 <!DOCTYPE html> <html lang="en"> <head ...
- 【试水CAS-4.0.3】第01节_CAS服务端搭建及导入源代码到MyEclipse
完整版见https://jadyer.github.io/2015/07/16/sso-cas-server-demo/ /** * @see ---------------------------- ...
- STL源码剖析(deque)
deque是一个双向开口的容器,在头尾两端进行元素的插入跟删除操作都有理想的时间复杂度. deque使用的是分段连续线性空间,它维护一个指针数组(T** map),其中每个指针指向一块连续线性空间. ...
- struts2 页面向Action传参方式
1.基本属性注入 我们可以直接将表单数据项传递给Action,而Action只需要提供基本的属性来接收参数即可,这种传参方式称为基本属性注入.例如 jsp页面: <s:form method=& ...
- 自闭合标签-主动闭合标签-meta-link标签
<!DOCTYPE html><!--规定标准的html--><!--一个页在只有一对html标签--><!--标签的属性 指定英文--><htm ...
- 检查linux网络的状况
http://hi.baidu.com/dr_wang/blog/item/2952f7458659c306cefca3cc.html
- 运行第一个.net core程序
前置条件 ubuntu已安装.net core运行环境 分6步 mkdir netcore 创建一个项目文件夹 cd netcore 进入该文件夹 dotnet new new命令 用于创建一个 ...
- Postman---html中get和post的区别和使用
get和post的区别和使用 Html中post和get区别,是不是用get的方法用post都能办到? Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DEL ...
- python selenium --unittest 框架
转自:http://www.cnblogs.com/fnng/p/3300788.html 学习unittest 很好的一个切入点就是从selenium IDE 录制导出脚本.相信不少新手学习sele ...