C#基础知识系列三(类和结构体、String和StringBuilder、equals和==)

简介: 前言    这一节主要来了解一下类和结构体之间的异同点、以及针对String和StringBuilder的用法、equals和==,其实可以看出很多地方都用到了上一节的值类型和引用类型、堆栈和装箱拆箱操作吧,慢慢的应用于实践,让理论与实践结合起来。

前言

   这一节主要来了解一下类和结构体之间的异同点、以及针对String和StringBuilder的用法、equals和==,其实可以看出很多地方都用到了上一节的值类型和引用类型、堆栈和装箱拆箱操作吧,慢慢的应用于实践,让理论与实践结合起来。

类和结构体

类和结构体的不同点: 

  1.关键字不同 一个是class,一个是struct

  2.类型不同,一个是引用类型,一个是值类型(存储:一个堆区,一个栈区)。关于值类型和引用类型以及堆与栈详细可见http://www.cnblogs.com/aehyok/p/3504449.html

  3.成员不同,结构体没有默认的构造函数(可以添加)和没有析构函数,不可以使用abstract,protected,sealed修饰

  4.Struct变量使用完之后就自动解除内存分配,Class实例有垃圾回收机制来保证内存的回收处理

  5.继承性。结构不可以继承自另一个结构或被继承,但和类一样可以继承自接口

  6.在结构体中可以声明字段,但是声明字段的时候是不能给初始值的.

  7.实体类中如果我们没有显示的定义构造函数,那么会有一个隐式无参的构造函数(重载构造函数之后,需要显示声明无参构造函数),

    而在结构体中隐身无参的构造函数无论如何都存在

  8.在类中可以显示的定义无参的构造函数,而在结构体中我们不能显示的定义无参的构造函数

  9.结构体是可以New的,而结构体构造函数要求必须要为所有的字段赋值.即使是无参的构造函数,也会给值类型赋初值为0,引用类型赋初值为null

同:

  1.都有属性和方法

  2.和类一样可以继承自接口

String和StringBuilder

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

 StringBuilder    MyStringBuilder    =    new    StringBuilder("Hello    World!");   

  通过用一个重载的构造函数方法初始化变量,可以创建 StringBuilder 类的新实例,正如以下示例中所阐释的那样。

  设置容量和长度 
  虽然 StringBuilder 对象是动态对象,允许扩充它所封装的字符串中字符的数量,但是您可以为它可容纳的最大字符数指定一个值。此值称为该对象的容量,不应将它与当前 StringBuilder 对象容纳的字符串长度混淆在一起。例如,可以创建 StringBuilder 类的带有字符串“Hello”(长度为 5)的一个新实例,同时可以指定该对象的最大容量为 25。当修改 StringBuilder 时,在达到容量之前,它不会为其自己重新分配空间。当达到容量时,将自动分配新的空间且容量翻倍。可以使用重载的构造函数之一来指定 StringBuilder 类的容量。以下代码示例指定可以将 MyStringBuilder 对象扩充到最大 25 个空白。   

StringBuilder    MyStringBuilder    =    new    StringBuilder("Hello    World!",    25);   

另外,可以使用读/写    Capacity    属性来设置对象的最大长度。以下代码示例使用    Capacity    属性来定义对象的最大长度。

MyStringBuilder.Capacity    =    25;   

EnsureCapacity 方法可用来检查当前 StringBuilder 的容量。如果容量大于传递的值,则不进行任何更改;但是,如果容量小于传递的值,则会更改当前的容量以使其与传递的值匹配。

  也可以查看或设置 Length 属性。如果将 Length 属性设置为大于 Capacity 属性的值,则自动将 Capacity 属性更改为与 Length 属性相同的值。如果将 Length 属性设置为小于当前 StringBuilder 对象内的字符串长度的值,则会缩短该字符串。  

这里有篇关于站长大神的博文:使用string.Format需要注意的一个性能问题http://www.cnblogs.com/dudu/archive/2012/05/29/string_format_stringbuilder.html

StringBuilder,String.concat(),String+String 哪一个效率高?http://q.cnblogs.com/q/36917/

equals和==

对于值类型,如果对象的值相等,则相等运算符 (==) 返回 true,否则返回 false。

对于string 以外的引用类型,如果两个对象引用同一个对象,则 == 返回 true。对于 string 类型,== 比较字符串的值。

 ==操作比较的是两个变量的值是否相等。

 equals()方法比较的是两个对象的内容是否一致,equals也就是比较引用类型是否是对同一个对象的引用。

对于值类型的比较简单,在此我们主要来看引用类型:

    public class Person
    {
        public string Name { get; set; }
        public Person(string name)
        {
            this.Name = name;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {

            string a = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
            string b = new string(new char[] { 'h', 'e', 'l', 'l', 'o' });
            Console.WriteLine(a == b);
            Console.WriteLine(a.Equals(b));

            object g = a;
            object h = b;
            Console.WriteLine(g == h);
            Console.WriteLine(g.Equals(h));

            Person p1 = new Person("aehyok");
            Person p2 = new Person("aehyok");
            Console.WriteLine(p1 == p2);
            Console.WriteLine(p1.Equals(p2));


            Person p3 = new Person("aehyok");
            Person p4 = p3;
            Console.WriteLine(p3 == p4);
            Console.WriteLine(p3.Equals(p4));
            Console.ReadLine();
        }
    }

结果输出:

因为值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中。

==操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储的地址是否相同,即栈中的内容是否相同。
equals操作表示的两个变量是否是对同一个对象的引用,即堆中的内容是否相同。

而字符串是一个特殊的引用型类型,在C#语言中,重载了string 对象的很多方法方法(包括equals()方法),使string对象用起来就像是值类型一样。
因此在上面的例子中,字符串a和字符串b的两个比较是相等的。

而g.equals(h)用的是sting的equals()方法故相等(多态)。如果将字符串a和b作这样的修改:
        string a="aa";
        string b="aa";
则,g和h的两个比较都是相等的。这是因为系统并没有给字符串b分配内存,只是将"aa"指向了b。所以a和b指向的是同一个字符串(字符串在这种赋值的情况下做了内存的优化)。

对于p1和p2,也是内存中两个不同的对象,所以在内存中的地址肯定不相同,故p1==p2会返回false,又因为p1和p2又是对不同对象的引用,所以p1.equals(p2)将返回false。
对于p3和p4,p4=p3,p3将对对象的引用赋给了p4,p3和p4是对同一个对象的引用,所以两个比较都返回true。

目录
相关文章
|
23天前
|
开发框架 .NET C#
C#|.net core 基础 - 删除字符串最后一个字符的七大类N种实现方式
【10月更文挑战第9天】在 C#/.NET Core 中,有多种方法可以删除字符串的最后一个字符,包括使用 `Substring` 方法、`Remove` 方法、`ToCharArray` 与 `Array.Copy`、`StringBuilder`、正则表达式、循环遍历字符数组以及使用 LINQ 的 `SkipLast` 方法。
|
2月前
|
存储 C# 索引
C# 一分钟浅谈:数组与集合类的基本操作
【9月更文挑战第1天】本文详细介绍了C#中数组和集合类的基本操作,包括创建、访问、遍历及常见问题的解决方法。数组适用于固定长度的数据存储,而集合类如`List<T>`则提供了动态扩展的能力。文章通过示例代码展示了如何处理索引越界、数组长度不可变及集合容量不足等问题,并提供了解决方案。掌握这些基础知识可使程序更加高效和清晰。
72 2
|
3月前
|
安全 Java API
【Java字符串操作秘籍】StringBuffer与StringBuilder的终极对决!
【8月更文挑战第25天】在Java中处理字符串时,经常需要修改字符串,但由于`String`对象的不可变性,频繁修改会导致内存浪费和性能下降。为此,Java提供了`StringBuffer`和`StringBuilder`两个类来操作可变字符串序列。`StringBuffer`是线程安全的,适用于多线程环境,但性能略低;`StringBuilder`非线程安全,但在单线程环境中性能更优。两者基本用法相似,通过`append`等方法构建和修改字符串。
54 1
|
2月前
|
安全 Java
String、StringBuffer、StringBuilder的区别
这篇文章讨论了Java中String、StringBuffer和StringBuilder的区别。String是不可变的,每次操作都会产生新的对象,效率低且浪费内存。StringBuilder可以在原字符串基础上进行操作,不开辟额外内存,弥补了String的缺陷。StringBuffer和StringBuilder类似,但StringBuffer的方法是线程安全的。文章还列举了StringBuffer的常用方法,并提供了使用示例代码。最后总结了这三者的主要区别。
String、StringBuffer、StringBuilder的区别
|
18天前
|
canal 安全 索引
(StringBuffer和StringBuilder)以及回文串,字符串经典习题
(StringBuffer和StringBuilder)以及回文串,字符串经典习题
32 5
|
2天前
|
存储 安全 Java
String、StringBuffer 和 StringBuilder 的区别
【10月更文挑战第21天】String、StringBuffer 和 StringBuilder 都有各自的特点和适用场景。了解它们之间的区别,可以帮助我们在编程中更合理地选择和使用这些类,从而提高程序的性能和质量。还可以结合具体的代码示例和实际应用场景,进一步深入分析它们的性能差异和使用技巧,使对它们的理解更加全面和深入。
5 0
|
2月前
|
安全 Java
Java StringBuffer 和 StringBuilder 类详解
在 Java 中,`StringBuffer` 和 `StringBuilder` 用于操作可变字符串,支持拼接、插入、删除等功能。两者的主要区别在于线程安全性和性能:`StringBuffer` 线程安全但较慢,适用于多线程环境;`StringBuilder` 非线程安全但更快,适合单线程环境。选择合适的类取决于具体的应用场景和性能需求。通常,在不需要线程安全的情况下,推荐使用 `StringBuilder` 以获得更好的性能。
|
21天前
|
Java 程序员 C#
【类的应用】C#应用之派生类构造方法给基类构造方法传参赋值
【类的应用】C#应用之派生类构造方法给基类构造方法传参赋值
8 0
|
2月前
|
C# 数据安全/隐私保护
C# 一分钟浅谈:类与对象的概念理解
【9月更文挑战第2天】本文从零开始详细介绍了C#中的类与对象概念。类作为一种自定义数据类型,定义了对象的属性和方法;对象则是类的实例,拥有独立的状态。通过具体代码示例,如定义 `Person` 类及其实例化过程,帮助读者更好地理解和应用这两个核心概念。此外,还总结了常见的问题及解决方法,为编写高质量的面向对象程序奠定基础。
24 2
|
3月前
|
安全 Java API
Java系类 之 String、StringBuffer和StringBuilder类的区别
这篇文章讨论了Java中`String`、`StringBuffer`和`StringBuilder`三个类的区别,其中`String`是不可变的,而`StringBuffer`是线程安全的可变字符串类,`StringBuilder`是非线程安全的可变字符串类,通常在单线程环境下性能更优。
Java系类 之 String、StringBuffer和StringBuilder类的区别