• 深入理解using


    Using 的多重身份
    1:引入命名空间
    2:创建别名
    3:强制资源清理
    (一)引入命名空间
    存在的误区:
        using类似于Java语言的import指令,都是引入命名空间(Java中称作包)这种逻辑结构;而不同于C语言中的#include指令,用于引入实际的类库。
        using引入命名空间,并不等于编译器编译时加载该命名空间所在的程序集,程序集的加载决定于程序中对该程序集是否存在调用操作,如果代码中不存在任何调用操作则编译器将不会加载using引入命名空间所在程序集。因此,在源文件开头,引入多个命名空间,并非加载多个程序集,不会造成“过度引用”的弊端 。
    (二)创建别名
    使用using创建别名的用法规则是:Using MyName = namespace | type;其中namespace表示创建命名空间的别名;而type表示创建类型别名。
    例子:
        为命名空间创建别名
        using mySpace = LyMIT.myCIS.CommonClass;
        为类型创建别名
        using MyConsole = System.Console;
        MyConsole.WriteLine("应用了类的别名。");
          创建别名的另一个重要的原因在于同一cs文件中引入的不同命名空间中包括了相同名称的类型,为了避免出现名称冲突可以通过设定别名来解决。
    以using创建别名,解决了这种可能的命名冲突,当然也可以通过类型全名称来加以区分。
    namespace WindowsApplication1
    {
        using OneClass = ClassLibrary1.Class1;
        using TwoClass = ClassLibrary2.Class1;
        public partial class Form1 : Form
        {

            public Form1()
            {
                InitializeComponent();
            }
            private void Form1_Click(object sender, EventArgs e)
            {
                MessageBox.Show(OneClass.ShowClassInfo);
                MessageBox.Show(TwoClass.ShowClassInfo);
            }
        }
    }
    (三)资源清理
    由来:
        要理解清楚使用using语句强制清理资源,就首先从了解Dispose模式说起,而要了解Dispose模式,则应首先了解.NET的垃圾回收机制。 .NET提供了Dispose模式来实现显式释放和关闭对象的能力。
    Dispose模式
         Dispose模式是.NET提供的一种显式清理对象资源的约定方式,用于在.NET 中释放对象封装的非托管资源。因为非托管资源不受GC控制,对象必须调用自己的Dispose()方法来释放,这就是所谓的Dispose模式。从概念角度来看,Dispose模式就是一种强制资源清理所要遵守的约定;从实现角度来看,Dispose模式就是让要一个类型实现IDisposable接口,从而使得该类型提供一个公有的Dispose方法。

    • using语句提供了强制清理对象资源的便捷操作方式,允许指定何时释放对象的资源源。
    • 所有拥有非托管资源的类型都会实现Idisposable接口,如果我们忘记Dispose()方法,其中的非内存资源会在随后终结器执行时释放,这样对象在内存中存放的时间就比较长,应用程序对资源的清理比较慢。
    • C#中的using语句可以Dispose()方法被调用,我们可以在using语句中分配一个对象,C#编译器会为每一个对象自动产生一个try/finally块。
    • 下面的两端代码将生成一样的IL代码。

                string connStr = string.Empty;
                SqlConnection conn = null;
                //using 语句示例
                using (SqlConnection conn = new SqlConnection(connStr))
                {
                    conn.Open();
                }
                //try/finally块
                try
                {
                    conn = new SqlConnection(connStr);
                    conn.Open();
                }
                finally
                {
                    conn.Dispose();
                }
    误区:
          (1)对没有实现Idisposable()接口的对象使用using语句。
    例子:

    //object对象没有实现Idisposeable接口
    Using (object obj = Factory.CreateResource())
    {
        Console.WriteLine(obj.ToString());
    }
    //修正版本
    Object obj=Factory.CreateResource();
    Using (obj as Idsposeable)
    {
        Console.WriteLine(obj.ToString());
    }
          如果没有实现Idisopose接口,在上面的情况下,using语句退化为using(null),这种做法非常的安全,只是不会做任何的事情。
    (2) 潜在的资源泄漏
    SqlConnection conn=new SqlConnection(connStr);
    SqlCommand cmd=new SqlCommand(cmdStr,conn);
    Using(conn as IDisposeable)
    Using (cmd as Idisposeable)
    {
        conn.Open();
        cmd.ExecuteNonQuery();
    }
           确保任何实现了Idisposeable()接口的对象都在using和Try块中分配,否则有可能出现内存泄漏。
         一个方法中有多个需要释放的资源的对象时,可以创建多个using块,或者自己写一个try/finally块,两种方法是等效的,产生的IL代码是完全一样的。
    有些对象既实现了Dispose()又实现了Close()。
         Dispose()除了释放资源外,还会通知垃圾回收器这个对象不再需要终结操作。Dispose()通过GC.SuppressFinaize()方法来实现这一点,Close()一般不会这么做。因此调用过Close()的对象仍然留在终结队列中,Dispose()不会将对象从内存中删除,它只是让对象释放非托管资源。
  • 相关阅读:
    Codeforces Round #497 (Div. 2) B. Turn the Rectangles
    Codeforces Round #497 (Div. 2) A. Romaji
    [DFS] [洛谷] P1219 八皇后 O(1)判断
    [归并] [STL] [洛谷] P1309 瑞士轮
    [贪心] [洛谷] P1803 凌乱的yyy / 线段覆盖
    [模拟] [洛谷] P1071 潜伏者
    java.io.EOFException: End of File Exception between local host is: "master/192.168.***.***"; destination host is: “master”:9000; :
    hadoop 无法打开网页和重新格式化问题
    hadoop平台环境搭建
    无法创建新虚拟机: 无法打开配置文件“F:BigDatavm12centos01centos01.vmx”: 拒绝访问。
  • 原文地址:https://www.cnblogs.com/noviceliu/p/1408440.html
Copyright © 2020-2023  润新知