string

C#有string关键字,在翻译成.NET类时,它就是System.String.有了它,像字符串连接和字符串复制这样的操作就简单了.

1  string 是引用类型还是值类型

引用类型操作

当使用重载操作符”=”给string对象赋值时,string的对象是引用类型,它保留在堆上,而不是堆栈上.因此,当把一个字符串赋给另一个字符串时,会得到对内存中同一个字符串的两个引用.例如,修改其中一个字符串,就会创建一个全新的string对象(注意,这个过程发生在”=”),而另一个字符串没有改变.考虑下面的代码:

public class MyClass

{

public static void Main()

{

string str1 = "I am a number";

string str2 = str1;

Console.WriteLine("str1 = "+str1);

Console.WriteLine("str2 = "+str2);

str1 = "I am another number";

Console.WriteLine("after str1 changed... str1 = "+str1);

Console.WriteLine("after str1 changed... str2 = "+str2);

Console.ReadLine();

}

}

Output :

str1 = I am a number

str2 = I am a number

after str1 changed...str1 = I am another number

after str1 changed...str2 = I am a number

具有值类型特征的操作

string有两种情况下的操作是具有值类型特征的:

1)        在函数中传递string(比如函数参数是string型)时,传递的是地址,但却不能修改成员变量,原因是它重新又创建了一个全新的对象,和它想修改的那个成员变量非同一地址,所以看上去像是值类型;

2)        str1 == str2 ,仅仅是比较了值,而非地址(是MS重写了==运算符所致).

总结:

string 到底是引用类型还是值类型   答:引用类型 .   只不过它在某此操作上会表现出值类型的特征.

string类型的另外一个特殊性在于它是“不会变”的,每次操作string,都相当于新建了一个string对象.

2  ”@”string中的用法

都知道如果要使用转义字符的话,需要在字符前加上”/”,而C#提供了一种新的机制,使用”@”.在”@”后的字符串都看作是原意,不会解释为转义字符串.并且以”@”开头的字符串支持回车换行的显示方式(见下例).不过会增加到字符串长度,不推荐过多使用.

public class MyClass

{

public static void Main()

{

string str1 = @"HelloWorld!";

string str2 = @"line1: Hello

line2: World!";

Console.WriteLine("str1 length = "+str1.Length);

Console.WriteLine("str2 length = "+str2.Length);

Console.ReadLine();

}

}

Output :

str1 length = 11

str2 length = 34

3  String string 的区别:

String是CLR(运行时库)的类型名字,而string是C#中的关键字.其实C#在编译时,会增加代码(下面列出的),将string转换成System.String.

using string = System.String;

using sbyte = System.SByte;

using byte = System.Byte;

using short = System.Int16;

using ushort = System.UInt16;

using int = System.Int32;

using uint = System.UInt32;

4  ”@”的其它用法

       在 C#  规范中, ”@”可以作为标识符(类名、变量名、方法名等)的第一个字符,以允许C# 中保留关键字作为自己定义的标识符.

public class MyClass

{

public static void Main()

{

@class c = new @class();

c.@static();

Console.ReadLine();

}

public class @class

{

private int @bool;

public void @static()

{

Console.WriteLine("I've been staticed...and @bool is "+this.@bool);

}

public @class()

{

this.@bool = 999;

}

}

}

5  等于null 等于””的区别

       string = null; //不分配内存

string = “”;     //分配字节为0的内存

Net 框架程序设计(修订版)中有这样一段描述:String类型直接继承自Object,这使得它成为一个引用类型,也就是说线程上的堆栈上不会驻留有任何字符串。(译注:注意这里的“直接继承”。直接继承自Object的类型一定是引用类型,因为所有的值类型都继承自System.ValueType。值得指出的是System.ValueType却是一个引用类型)。

  一:

string str1 = "string";
string str2 = "string"; 
Console.WriteLine(string.ReferenceEquals(str1, str2));

 既然String类型是引用类型,那么代码一输出的应该是False,然而事实上代码一输出时的是True。

  其实这是String类型的自动优化功能。str1,str2引用同一对象,节省内存,并不会为str2单独开辟内存空间。CLR使用了一种叫字符串驻留的技术,当CLR初始化时,会创建一个内部的散列表,其中的键为字符串,值为指向托管堆中字符串的引用。刚开始,散列表为空,JIT编译器编译方法时,会在散列表中查找每一个文本常量字符串,首先会查找"abc"字符串,并且因为没有找到,编译器会在托管堆中构造一个新的指向"abc"的String对象引用,然后将"abc"字符串和指向该对象的引用添加到散列表中。接着,在散列表中查找第二个"abc",这一次由于找到了该字符串,指向同一个String对象的引用会被保存在变量str2中,到此str1和str2指向了同一个引用,所以string.ReferenceEquals(str1, str2)就会返回true了。

  另外,C#中是不允许用new操作符创建String对象的,编译器会报错。

  二:

static void Main(string[] args) {
  string str = "string"; 
  Change(str); 
  Console.WriteLine(str); 
static void Change(string str) { 
  str = "Changed"; 
}

方法传递的参数是原内容的拷贝,其过程如果用图可表示为:

  语句str=”Changed”之前

  语句str=”Changed”之后

  这样可以看到原来String对象并未改变str=”Changed”只是创建一个新的String对象(其它引用类型是改变内存地址1指向的值),因此这个方法的参数需要加上ref或者out修饰符。因此这里也可以得出字符串具有恒等性,也就是说一个字符串一旦被创建,我们就不能再将其变长、变短、或者改变其中的任何字符。

  MSDN上这样解释:字符串对象是不可变的,即它们一旦创建就无法更改。对字符串进行操作的方法实际上返回的是新的字符串对象。

  string在另一种情况下的操作是具有值类型特征的:str1 == str2 ,仅仅是比较了值,而非地址(是MS重写了==运算符所致).

   三:

  String 对象是不可改变的。每次使用 System.String 类中的方法之一时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间。在需要对字符串执行重复修改的情况下,与创建新的 String 对象相关的系统开销可能会非常昂贵。如果要修改字符串而不创建新的对象,则可以使用 System.Text.StringBuilder 类。例如,当在一个循环中将许多字符串连接在一起时,使用 StringBuilder 类可以提升性能。

  下面看一个极简单的例子:

namespace TCP
{
public class Program
{
    public class User
      {
          private string _name;
          private string _age;
          public User(string name, string age)
          {
              _name = name;
              _age = age;
          }

  public string name
          {
              get { return _name; }
              set { _name = value; }
          }
          public string age
          {
              get { return _age; }
              set { _age = value; }
          }
      }

   }
 
   public static void editUser(User user, StringBuilder str,string code)
   {
     code = "VB.NET";
     str = str.Remove(0, 1);
     str.Append("E");
     user.name = "LEE";
user.age = "10";
}
  
static void Main(string[] args)
   {
     string code = "C#";
   User user = new User("Li","23");
     StringBuilder str = new StringBuilder();            
     str.Append("A");            
     editUser(user, str,code);

     Console.WriteLine(code);
     Console.WriteLine(str);
     Console.WriteLine(user.name);
     Console.WriteLine(user.age);
     Console.ReadLine();

   }

}

上面代码输如下:

从上面可以看到string类型的值并没有改变,StringBuilder与class的值都改变了。

C#中特殊的string类型的更多相关文章

  1. ArrayList list = new ArrayList()在这个泛型为Integer的ArrayList中存放一个String类型的对象

    java面试要点---ArrayList list = new ArrayList(); 在这个泛型为Integer的ArrayList中存放一个String类型的对象. ArrayList list ...

  2. Java 中要将 String 类型转化为 int 类型

    在 Java 中要将 String 类型转化为 int 类型时,需要使用 Integer 类中的 parseInt() 方法或者 valueOf() 方法进行转换. 例1: 1 2 3 4 5 6 S ...

  3. java中特殊的String类型

    Java中String是一个特殊的包装类数据有两种创建形式: String s = "abc"; String s = new String("abc"); 第 ...

  4. 【转】Java中特殊的String类型

    Java中String是一个特殊的包装类数据有两种创建形式: String s = "abc"; String s = new String("abc"); 第 ...

  5. redis中关于使用string类型还是hash类型

    前篇:最近在做一个将redis中大数据量进行合并缩减优化的工作,其中一项按月将数据进行合并.将一个月的数据放入一个key-value键值对中. 例:p2d20180901-3.p2d20180902- ...

  6. JAVA中int转String类型有三种方法

    String.valueOf(i) Integer.toString(i) i+"" i+""也就是一个int型的常量.+上个空的字符串,这里牵涉到了strin ...

  7. JAVA中int与String类型的相互转换

    Java的int和String类型间互相转换,小功能但是经常用到,下面是几种实现的方法: 字符串类型String转换成整数int 1. int i = Integer.parseInt([String ...

  8. Java中int和String类型之间转换

    int –> String int i=123; String s=""; 第一种方法:s=i+""; //会产生两个String对象 第二种方法:s=S ...

  9. 将xml 写到内存中再已string类型读出来

    System.IO.MemoryStream ms = new System.IO.MemoryStream(); xmlDoc.Save(ms); System.IO.StreamReader sr ...

随机推荐

  1. 2018年总结和2019年的Flag

    ---恢复内容开始--- 目前截止到现在工作将近一年半了,今天工作上主要后端主要是用了两种语言,java和Python(2.7),今年完成主要的工作主要使用Python在写一些脚本来满足财务和人资部门 ...

  2. The type javax.xml.rpc.ServiceException cannot be resolved.It is indirectly

    The type javax.xml.rpc.ServiceException cannot be resolved.It is indirectly 博客分类: 解决方案_Java   问题描述:T ...

  3. (转)Android中的基类—抽取出来公共的方法

    在Android中,一般来说一个应用会存在几十个页面,并且一个应用一般也会使用一个特定的主题,其中的页面的风格也是一致的,并且页面中的动画效果.页面的切换效果等也应该保持同样的风格,那么就需要一个基类 ...

  4. The method of type must override a superclass method解决方式(转)

    今天做struts2上传文件的时候出现了这个问题: The method execute() of type UploadAction must override or implement a sup ...

  5. CodeReview是开发中的重要一个环节,整理了一些关于jupiter for java

    什么是代码评审(CodeReview)? 代码评审也称代码复查,是指通过阅读代码来检查源代码与编码标准的符合性以及代码质量的活动. Jupiter提供了代码行级别的评审批注功能,方便评审参与人了解具体 ...

  6. php-fpm使用

    /usr/local/php/sbin/php-fpm  --help -c <path>|<file> Look for php.ini file in this direc ...

  7. log4net内部调试开启

    最近用log4net写入日志到mysql数据库,死活写不进去,就想能不能看log4net的错误记录,在网上一找,还真有:开启log4net的内部调试,作个记录: <appSettings> ...

  8. Avro之二:入门demo

    一.使用avro-maven插件为avsc文件生成对应的java类: 在项目的pom.xml中增加依赖及插件如下: <dependency> <groupId>org.apac ...

  9. HDU 4547 CD操作 (LCA最近公共祖先Tarjan模版)

    CD操作 倍增法  https://i.cnblogs.com/EditPosts.aspx?postid=8605845 Time Limit : 10000/5000ms (Java/Other) ...

  10. modelform实例学习

    先来回顾下form的用法 一对多关系,form显示的是下拉框 多对多关系,form显示的是多选框 modelform的用法 modelsform的写法 from django.forms import ...