• C#里字符串驻留的几个小测试


    在看anytao的《你必须知道的.NET》 http://www.cnblogs.com/anytao/archive/2008/08/27/must_net_22.html,看到字符串驻留这部分时,对于里面提到的几个问题有些小疑问,特别是后面几个问题,没看懂,所以特地做了些小测试,也不知是否正确,或者说那里表达得有问题,请了解这方面的大侠们多指点。

    该说的在代码里已经说,其他的就不废话了

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 
     6 namespace Test
     7 {
     8    
     9 
    10     class Program
    11     {
    12         const string strConst = "strConst";//编译时确定,存放在元数据里,被访问之前不会被加载到内存
    13         readonly static string strStatic = "strStatic";//运行时确定
    14 
    15         static void Main(string[] args)
    16         {
    17             string s0 = "str";
    18 
    19             //下面这个测试说明了:两个字符串动态“相加”后得到的字符串是在运行时去确定的,不会添加到字符串池里
    20             #region 测试动态生成的string
    21 
    22             string s1 = s0 + "Test";//s2由两个字符串动态“相加”得到,由IL代码可知是调用 string String::Concat(string, string)方法后取返回值得到
    23             Console.WriteLine("s1 is (test Concat): " + string.IsInterned(s1));
    24 
    25             #endregion
    26 
    27 
    28             //下面这个测试说明了:如果const string 没有被访问,那么就不会被添加到字符串池里
    29             #region 测试 const string
    30 
    31             //执行下面这句代码时,编译器会直接把字符串 "strConst" 嵌入到代码来替代 常量strConst,
    32             //这样子就会导致将字符串 "strConst" 加入到字符串池里(如果字符串池没有这个项)。所以这样子测试是不准确的
    33             // Console.WriteLine(string.IsInterned(strConst));
    34 
    35             //const string 在编译时嵌入到代码替换对应的那个常量;当const string 所在的方法被调用时,该const string就被添加到字符串池里
    36             
    37             string s2 = s0 + "Const";
    38             Console.WriteLine("s2 is (test const string): " + string.IsInterned(s2));
    39             //Console.WriteLine(strConst);
    40             //Console.WriteLine("s4 is: " + string.IsInterned(s4));
    41 
    42             #endregion
    43 
    44 
    45             //下面这个测试说明了:static string 在类型任一个成员被访问之前就已经被添加到字符串池里了
    46             #region 测试static string
    47 
    48             //static string,在这个类型的任何一个成员被访问之前,CLR会调动类型的类型构造器,也就是静态构造器(可显式定义,但只能有一个,必须无参)
    49             //类型构造器先调用static成员的初始化代码,再调用自己显式添加的代码。所以static string初始化时赋予的字符串会被添加到字符串池
    50 
    51             string s3 = s0 + "Static";
    52             Console.WriteLine("s3 is (test static string): " + string.IsInterned(s3));
    53 
    54             #endregion
    55 
    56 
    57             //下面这个测试说明了:字符串不在乎声明得前面还是后面,因为字符串常量是在编译时确定的,
    58             //反正在方法被访问时,方法就被加载到内存,里面所有的字符串常量一次性全部添加到字符串池里
    59             #region 测试先输出后定义
    60 
    61            // string s7 = strConst;//在编译的时候直接用常量strConst的内容 "strConst" 嵌入代码替代 s7;从而添加进了字符串池
    62 
    63             string s4 = s0 + "before define";
    64             Console.WriteLine("s4 is (test before define): " + string.IsInterned(s4));
    65 
    66             //在编译的时候就已经把 "strbefore define" 放到字符串池里了。如果是放在其他函数里,为什么不也在编译的时候就放到字符串池里?
    67             string s40 = "strbefore define";
    68 
    69             #endregion
    70 
    71 
    72             //下面这个测试说明了:方法被调用前,里面所有的东西都只是在元数据里,没有被加载到内存;
    73             //当某方法被调用时才会被加载到内存,方法的所有文本字符串一次性添加到字符串池里
    74             #region 调用方法
    75 
    76             string s5 = s0 + "Change";
    77             Console.WriteLine("s5 is (before mothed): " + string.IsInterned(s5));//调用方法前,"strChange" 没有被添加到字符串池里
    78             StrChange();
    79             Console.WriteLine("s5 is (after mothed) : " + string.IsInterned(s5));//调用方法后,"strChange" 已经被添加到字符串池里了 
    80 
    81 
    82             #endregion
    83 
    84             Console.ReadKey();
    85         }
    86 
    87 
    88         //方法里的字符串常量在编译时就会嵌入到代码里
    89         //方法被调用之前只是以IL代码的形式存放在元数据里,没有被加载到内存里;当方法被调用时才会被加载到内存,方法里的所有文本字符串常量就全部添加到字符串池里
    90         static string StrChange()
    91         {
    92             return "strChange";
    93         }
    94     }
    95 
    96 }
  • 相关阅读:
    C# 中字符串转换成日期
    c#中退出WinForm程序包括有很多方法,如:this.Close(); Application.Exit();Application.ExitThread(); System.Environment.Exit(0);
    c#获取程序版本号
    分分钟用上C#中的委托和事件
    【转载】C# 中的委托和事件(详解:简单易懂的讲解)
    C#什么时候需要使用构造函数
    15、生命周期-BeanPostProcessor-后置处理器
    13、生命周期-InitializingBean和DisposableBean
    11、组件注册-使用FactoryBean注册组件
    12、生命周期-@Bean指定初始化和销毁方法
  • 原文地址:https://www.cnblogs.com/zouzf/p/2671116.html
Copyright © 2020-2023  润新知