new和using的区别

本文通过实例解析了C#中USING语句与DISPOSE方法的关系,揭示了USING如何帮助开发者自动调用DISPOSE进行资源清理,特别强调了在处理非托管资源时的适用场景。

        很多公司的面试都可能问或是考查这个看似基础的东西,恕我浑浑噩噩,我可能回答的不够好!习惯性质的是由于我可能知道一些东西,但由于事务缠身,并没有去过多的关注部分细节,其间也没有得到某些无意或是有意的灌输,我可能会回答区别在于一个不会自动释放资源,一个会。那USING为甚么会了?在甚么时候使用USING合适等。
        我不知道在后面的回答是否都能把握的好,这只能说明我不够精通,但这些题目从来就没有给别人这样一个机会,假如你回答的不好,你是否能通过一种途径来找出区别,然后你再重新回答。
我笑了,假如我回答的不够好,我觉得后面是一个机会(也是一种能力的考察),我会通过甚么途径了,ILDASM,至少我知道我们生活再.NET的“蜜糖”中,我们有了好的高层次的框架,我有了很好的开发效率,但我忽视了细节,有很多时候,甚至懒得去关心细节,但这个题目让我觉得很丢脸,我回答的不好(阴沟里还翻了船) ,但我自知,秘密就藏再后面,于是我解开一段DEMO,看个明白。

using  System;

namespace  Demo
{
        
class  Class1
    {
                [STAThread]
        
static   void  Main( string [] args)
        {
                        Test obj1
= new  Test();


            
using (Test obj2 = new  Test())
            {
            }
        }
    }

    
class  Test:System.IDisposable
    {
        
int  a;
        
public   int  Val
        {
            
get
            {
                
return  a;
            }
        }
        
#region  IDisposable Members

        
public   void  Dispose()
        {
                    }

        
#endregion
    }
}

上面代码对应的IL语言解开了USING的秘密:

.method  private  hidebysig  static   void   Main( string [] args) cil managed
{
  .entrypoint
  .custom instance 
void  [mscorlib]System.STAThreadAttribute::.ctor()  =  (  01   00   00   00  ) 
  
//  Code size       25 (0x19)
  .maxstack   1                                             ---推导堆栈 
  .locals init ([
0 class  Demo.Test obj1,
           [
1 class  Demo.Test obj2)                --定义了两局部变量
  IL_0000:  newobj     instance 
void  Demo.Test::.ctor()
  IL_0005:  stloc.
0     -- 创建了Test对象并存放到 第一个局部量
  IL_0006:  newobj     instance 
void  Demo.Test::.ctor()
  IL_000b:  stloc.
1    -- 创建了Test对象并存放到第二个局部量
  .
try
  {
    IL_000c:  leave.s    IL_0018  -- 你可以看作是GOTO语句 ,但是你要清楚,异常和RETURN,GOTO都不能逃出FINALLY
  }  
//  end .try                                       FINALLY是一定会执行
   finally
  {
    IL_000e:  ldloc.
1                         --载入局部量1,也是就我们用USING扩起的那个局部量)
    IL_000f:  brfalse.s  IL_0017        --发现,如果这个对象是NULL的,就结束  ,否则就调用对象上的DISPOSE方法,哦原来如此
    IL_0011:  ldloc.
1                       -- 我们终于发现了秘密, ^_^ ,假如面试前你正好研究过,你回答的是否就更清晰!
    IL_0012:  callvirt   instance 
void  [mscorlib]System.IDisposable::Dispose()
    IL_0017:  endfinally
  }  
//  end handler
  IL_0018:  ret
//  end of method Class1::Main

现在我要回答后面的问题了,是框架帮我做了手脚,他强制帮我调用对象的DISPOSE资源释放方法,而且,如果你的对象没有实现此IDISPOSABLE接口,却用了USING,编译是不会通过的哟!这里看来,USING的时机是当对象使用了非托管资源或是比较宝贵的资源,
而对于托管的或非宝贵的资源,我可以依赖GC(垃圾回收机制,garbage collection),没有必要自己画蛇添足。而且TRY块是会影响效率的。

转自:http://www.cnblogs.com/bytekiller/archive/2007/06/21/792411.html 

<think>嗯,用户想了解C#中usingnew关键字的用法或区别。首先,我得回忆一下这两个关键字的基本用途,以及它们在不同上下文中的不同作用。 首先,new关键字在C#中有几个主要用途。最常见的应该是用于创建对象实例,比如`var obj = new MyClass();`。另外,在继承中,new关键字可以用于隐藏基类的成员,当子类有一个与基类同名的方法时,可以用new来显式隐藏,避免警告。还有在泛型中,new()约束用来指定类型参数必须有公共无参构造函数。这些情况需要分别说明。 然后是using关键字。using主要有三个用途:第一个是作为指令引用命名空间,比如`using System.IO;`,这样在代码中就可以直接使用该命名空间下的类,而不需要全限定名。第二个是作为语句定义资源范围,确保对象在离开作用域时被释放,比如`using (var file = new FileStream(...)) { ... }`,这其实是实现了IDisposable接口的对象自动调用Dispose方法。第三个是C# 8.0引入的using声明,可以简化代码,比如`using var file = new FileStream(...);`,这样对象会在声明的作用域结束时自动释放,不需要大括号包裹。 接下来需要比较它们的区别。作用上,new主要用于实例化成员隐藏,而using用于资源管理命名空间引用。生命周期管理方面,new创建对象,但不管释放;using确保资源释放。语法上下文也不同,new可以出现在表达式或成员声明中,using可以是指令、语句或声明。版本差异的话,using声明是C# 8.0新增的,而new的功能在早期版本就存在。 用户可能还关心实际应用中的例子,比如如何正确使用using来管理资源,避免内存泄漏。另外,可能需要提到在使用new隐藏基类成员时的注意事项,比如应该使用override而不是new,如果基类方法被标记为virtual的话。 还需要注意引用中的内容,比如引用[4]提到GC的高效使用,可能using有关,因为using帮助及时释放资源,减少GC压力。引用[1]中关于refout的内容可能暂时不相关,但用户的问题集中在usingnew,所以重点放在这两个关键字上。 总结结构应该先分别介绍两个关键字的用法,再对比区别,最后回答相关问题。需要确保例子正确,语法符合LaTeX要求,比如行内公式用$...$,独立公式用$$...$$。同时,生成的相关问题要围绕这两个关键字的应用场景、常见错误、版本差异等。</think>### C#中`using`与`new`关键字的用法与区别 #### 一、`new`关键字的用法 1. **对象实例化** `new`用于创建类的实例并调用构造函数: ```csharp var obj = new MyClass(); // 创建MyClass的实例[^4] ``` 2. **隐藏基类成员** 当子类需要隐藏基类同名成员时,使用`new`显式声明: ```csharp public class BaseClass { public void Method() { } } public class DerivedClass : BaseClass { public new void Method() { } // 隐藏基类的Method方法[^3] } ``` 3. **泛型约束** 在泛型中约束类型参数必须有公共无参构造函数: ```csharp public T Create<T>() where T : new() => new T(); ``` --- #### 二、`using`关键字的用法 1. **命名空间引用** 简化类型名称的访问路径: ```csharp using System.IO; // 直接使用FileStream等类型 ``` 2. **资源管理(`IDisposable`接口)** 自动释放非托管资源(如文件句柄、数据库连接): ```csharp using (var file = new FileStream("test.txt", FileMode.Open)) { // 操作完成后自动调用file.Dispose() } ``` 3. **C# 8.0的`using`声明** 简化资源管理语法(作用域结束时自动释放): ```csharp using var file = new FileStream("test.txt", FileMode.Open); // 作用域结束时自动释放 ``` --- #### 三、核心区别对比 | 特性 | `new`关键字 | `using`关键字 | |---------------------|--------------------------------------|----------------------------------------| | **主要作用** | 实例化对象、隐藏成员、泛型约束 | 资源管理、命名空间引用 | | **生命周期管理** | 不控制资源释放 | 确保资源及时释放[^4] | | **语法上下文** | 表达式或成员声明 | 指令、语句或声明 | | **版本依赖** | 所有C#版本 | `using`声明需C# 8.0+ | --- #### 四、典型应用场景 1. **`new`的适用场景** - 需要动态创建对象时(如工厂模式) - 子类需覆盖基类非虚方法时 - 泛型类型需要实例化约束时 2. **`using`的适用场景** - 操作文件、网络连接等需要及时释放的资源 - 简化`try-finally`块中的资源清理代码 - 避免因异常导致资源泄漏 --- #### 五、常见错误示例 1. **误用`new`隐藏虚方法** ```csharp public class Base { public virtual void Method() { } } public class Derived : Base { public new void Method() { } // 应使用override而非new } ``` 2. **忽略`using`导致资源泄漏** ```csharp var file = new FileStream("test.txt", FileMode.Open); // 未释放! // 正确写法:使用using语句 ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值