首页 > 应用开发 > C/C++ > 从String类型发散想到的一些东西
[Fact] public void Base_Test() { string a = "abc"; string b = "abc"; //字符串的留存性,初始化后会放入常量池,b直接引用a的对象 Assert.True(string.ReferenceEquals(a, b)); string c = new String("abc"); string d = new String("abc"); //直接new的话,会重新分配内存 Assert.False(string.ReferenceEquals(c, d)); Assert.False(string.ReferenceEquals(a, c)); string e = "abc"; //这里e还是使用字符串的留存性,且使用的还是a的地址。证明c分配的内存引用并没有放入常量池替换 Assert.True(string.ReferenceEquals(a, e)); Assert.False(string.ReferenceEquals(c, e)); string f = "abc" + "abc"; string g = a + b; string h = "abcabc"; //f在编译期间确定,实际还是从常量池中获取 //IsInterned 表示从常量池中获取对应的字符串,获取失败返回null //a+b实际上是发生了字符串组合运算,内部重新new了一个新的字符串,所以f,g引用地址不同 Assert.False(string.ReferenceEquals(f, g)); Assert.True(string.ReferenceEquals(string.IsInterned(f), h)); Assert.True(string.ReferenceEquals(f, h)); }
string a="b"+"c" ,实际上创建了3个字符串"b"、"c"、"bc"。所以在这个时候就需要StringBuilder来专门执行字符串拼接操作了。Capacity 属性,用于定义数组的初始容量,默认值为25。超过容量会触发扩容操作。所以在实际操作中,如果我们能预估到拼接字符串的长度,在定义StringBuilder给
Capacity 属性附上一个合理的值,将会有更加高效的性能。StringComparisonpublic enum StringComparison { // // 摘要: // 使用区分区域性的排序规则和当前区域性比较字符串。 CurrentCulture = 0, // // 摘要: // 通过使用区分区域性的排序规则、当前区域性,并忽略所比较的字符串的大小写,来比较字符串。 CurrentCultureIgnoreCase = 1, // // 摘要: // 使用区分区域性的排序规则和固定区域性比较字符串。 InvariantCulture = 2, // // 摘要: // 通过使用区分区域性的排序规则、固定区域性,并忽略所比较的字符串的大小写,来比较字符串。 InvariantCultureIgnoreCase = 3, // // 摘要: // 使用序号(二进制)排序规则比较字符串。 Ordinal = 4, // // 摘要: // 通过使用序号(二进制)区分区域性的排序规则并忽略所比较的字符串的大小写,来比较字符串。 OrdinalIgnoreCase = 5 }
ref
out 关键字实现。对于值类型,会直接传入原对象在栈上的引用。对于引用类型,会传入原有对象的堆地址的引用。 [Fact] public void Base_Test() { //引用类型参数 TestClass s = new TestClass(); s.Tag = "abc"; TestMethod m = new TestMethod(); m.ReNew(s); //参数s 实际是对象 s的 地址拷贝。两者在栈上不同,但是指向的堆地址相同 //在ReNew方法中 "参数s" 重新指向了一个新的对象,但是不影响旧的对象s Assert.True(string.Equals("abc", s.Tag)); m.Change(s, "123"); //Change方法是直接修改 参数s 指向的堆对象内的字段数据,所有对象s字段也发生了变化 Assert.True(string.Equals("123", s.Tag)); m.ReNew2(ref s); //注意和ReNew的区别,因为是ref 引用传递,所有原对象引用地址指向了新new的对象地址 Assert.False(string.Equals("abc", s.Tag)); Assert.True(string.Equals("cba", s.Tag)); //值类型参数 int val = 100; //Change方法内部改变了val的值,但不影响val原来的值 m.Change(val); Assert.True(val == 100); m.Change(out val); //使用out标记,改变了val原来的值 Assert.True(val == 123); } } public class TestMethod { public void ReNew(TestClass c) { c = new TestClass() { Tag = "cba" }; } public void ReNew2(ref TestClass c) { c = new TestClass() { Tag = "cba" }; } public void Change(TestClass c, string tag) { c.Tag = tag; } public void Change(int a) { a = 123; } public void Change(out int a) { a = 123; } } public class TestClass { public string Tag { get; set; } }
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69983768/viewspace-2722517/ ,如需转载,请注明出处,否则将追究法律责任。