C#基础教程之类class与结构struct的区别

 更新时间:2022年11月03日 11:42:36   作者:斯内科  
struct是值类型,创建一个struct类型的实例被分配在栈上,class是引用类型,创建一个class类型实例被分配在托管堆上,下面这篇文章主要给大家介绍了关于C#基础教程之类class与结构struct区别的相关资料,需要的朋友可以参考下

一、类class

类class是引用类型,可以直接赋值为null,默认值也是null

XClass xClass = null;//语法正确

一般来说,某个类对象使用另一个类的对象赋值时,则两者共用一个内存地址【节约内存空间】,ReferenceEquals引用比较此时返回true

            XClass xClass3 = new XClass() { Id = 7, Name = "天晴之海" };
            XClass xClass4 = xClass3;

类的构造函数(构造方法)

如果一个类没有显示定义构造函数,则默认有一个无参构造函数,

如果一个类已定义了带参数的构造函数,如果不手动定义无参构造函数,则没有无参构造函数

特殊类String:

特殊类【字符串String】虽然是引用类型,但对字符串的更新并不会修改字符串的原实际值,

字符串作为参数传递并不能篡改原来的值,

可以认为字符串虽然是引用类型,但使用时按值类型处理

二、结构struct

结构struct是值类型,不能直接赋值为null,结构的默认值为0,false,类型名称字符串等

XStruct xStruct=null;//语法错误,不能为值类型赋值为null

如果想为值类型赋值为null,请使用可空类型Nullable<T>

public struct Nullable<T> where T : struct

比如如下代码即可编译通过:

Nullable<XStruct> xStruct = null;//可空值类型

或者简化为

XStruct? xStruct = null;//可空值类型的简化

    某个结构对象使用另一个结构的对象赋值时,则两者的内存地址完全不同,第二个结构对象新开一个内存空间,只不过内存的值完全一致【内存空间增加】,ReferenceEquals引用比较此时返回false

结构的构造函数

所有结构都自动继承抽象值类型基类ValueType,有个默认无参构造函数ValueType(),因此无法在自定义结构中定义无参构造函数

using System.Runtime.InteropServices;
using System.Security;
 
namespace System
{
    //
    // 摘要:
    //     为值类型提供基类。
    [ComVisible(true)]
    public abstract class ValueType
    {
        //
        // 摘要:
        //     初始化 System.ValueType 类的新实例。
        protected ValueType();
 
        //
        // 摘要:
        //     指示此实例与指定对象是否相等。
        //
        // 参数:
        //   obj:
        //     要与当前实例进行比较的对象。
        //
        // 返回结果:
        //     如果 true 和该实例具有相同的类型并表示相同的值,则为 obj;否则为 false。
        [SecuritySafeCritical]
        public override bool Equals(object obj);
        //
        // 摘要:
        //     返回此实例的哈希代码。
        //
        // 返回结果:
        //     一个 32 位带符号整数,它是此实例的哈希代码。
        [SecuritySafeCritical]
        public override int GetHashCode();
        //
        // 摘要:
        //     返回此实例的完全限定类型名称。
        //
        // 返回结果:
        //     完全限定的类型名称
        public override string ToString();
    }
}

值类型重写了Equals方法,如果一个值类型的具体属性值完全一致时,两个对象是相等的

三、测试控制台应用程序GenericTemplateDemo:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace GenericTemplateDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.SetWindowSize(120, 30);
            Console.WriteLine($"结构的默认值为类型名(一定不为null):{default(XStruct)},类型名为【{typeof(XStruct)}】");
            Console.WriteLine($"类的默认值为null?【{default(XClass) == null}】");
            Console.WriteLine("---------------------------------结构的Equal比较---------------------------------");
            XStruct xStruct1 = new XStruct() { Id = 5, Name = "ABC" };
            XStruct xStruct2 = new XStruct("ABC") { Id = 5 };
            Console.WriteLine($"结构一的内容{{Id:{xStruct1.Id},Name:{xStruct1.Name}}}");
            Console.WriteLine($"结构二的内容{{Id:{xStruct2.Id},Name:{xStruct2.Name}}}");
            Console.WriteLine();
            Console.WriteLine($"比较两个结构的实例值是否相等:{xStruct1.Equals(xStruct2)}");
            Console.WriteLine($"比较两个结构的引用是否指向同一个实例:{ReferenceEquals(xStruct1, xStruct2)}");
 
            XStruct xStruct3 = new XStruct("修吾") { Id = 8 };
            XStruct xStruct4 = xStruct3;
            Console.WriteLine($"结构三的内容{{Id:{xStruct3.Id},Name:{xStruct3.Name}}}");
            Console.WriteLine($"结构四的内容{{Id:{xStruct4.Id},Name:{xStruct4.Name}}}");
            Console.WriteLine();
            Console.WriteLine($"比较两个结构的实例值是否相等:{xStruct3.Equals(xStruct4)}");
            Console.WriteLine($"比较两个结构的引用是否指向同一个实例:{ReferenceEquals(xStruct3, xStruct4)}");
            Console.WriteLine("---------------------------------类的Equal比较---------------------------------");
            XClass xClass1 = new XClass() { Id = 6, Name = "毒瘴泉" };
            XClass xClass2 = new XClass("毒瘴泉") { Id = 6 };
            Console.WriteLine($"类一的内容{{Id:{xClass1.Id},Name:{xClass1.Name}}}");
            Console.WriteLine($"类二的内容{{Id:{xClass2.Id},Name:{xClass2.Name}}}");
            Console.WriteLine();
            Console.WriteLine($"比较两个类的实例值是否相等:{xClass1.Equals(xClass2)}");
            Console.WriteLine($"比较两个类的引用是否指向同一个实例:{ReferenceEquals(xClass1, xClass2)}");
            Console.WriteLine();
            XClass xClass3 = new XClass() { Id = 7, Name = "天晴之海" };
            XClass xClass4 = xClass3;
            Console.WriteLine($"类三的内容{{Id:{xClass3.Id},Name:{xClass3.Name}}}");
            Console.WriteLine($"类四的内容{{Id:{xClass4.Id},Name:{xClass4.Name}}}");
            Console.WriteLine();
            Console.WriteLine($"比较两个类的实例值是否相等:{xClass3.Equals(xClass4)}");
            Console.WriteLine($"比较两个类的引用是否指向同一个实例:{ReferenceEquals(xClass3, xClass4)}");
            Console.ReadLine();
        }        
    }
 
    /// <summary>
    /// 测试用的结构,结构继承ValueType,而ValueType重写了Equals(object obj)方法,因此比较
    /// 结构不允许显式定义无参的构造函数,因 结构struct一经定义,自动会生成一个无参构造函数
    /// </summary>
    struct XStruct
    {
        public XStruct(string name)
        {
            Id = 0;
            Name = name;
        }
        public int Id { get; set; }
        public string Name { get; set; }
    }
 
    /// <summary>
    /// 测试用的类
    /// </summary>
    class XClass
    {
        public XClass()
        {
        }
        public XClass(string name)
        {
            Id = 0;
            Name = name;
        }
        public int Id { get; set; }
        public string Name { get; set; }
    }
}

四、程序运行如图:

补充:结构与类的区别

1.类和结构有以下几个基本的不同点:

  • 类是引用类型,结构是值类型。
  • 结构不支持继承。
  • 结构不能声明默认的构造函数。
  • 结构体中声明的字段无法赋予初值,类可以
  • 类的对象是存储在堆空间中,结构存储在栈中。

2.选择使用情况

堆空间大,但访问速度较慢,栈空间小,访问速度相对更快。当我们描述一个轻量级对象的时候,结构可提高效率,成本更低。不过假如我们在传值的时候希望传递的是对象的引用地址而不是对象的拷贝,就应该使用类了。

总结

到此这篇关于C#基础教程之类class与结构struct区别的文章就介绍到这了,更多相关C# 类class与结构struct区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • js substr,substring与java substring和C# substring的区别解析

    js substr,substring与java substring和C# substring的区别解析

    本篇文章主要是对js中substr,substring与java中substring和C#中substring的区别进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2014-01-01
  • C# httpwebrequest访问HTTPS错误处理方法

    C# httpwebrequest访问HTTPS错误处理方法

    下面小编就为大家带来一篇C# httpwebrequest访问HTTPS错误处理方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • C# goto语句的具体使用

    C# goto语句的具体使用

    # goto 语句用于直接在一个程序中转到程序中的标签指定的位置,标签实际上由标识符加上冒号构成。本文主要介绍了C# goto语句的具体使用,感兴趣的可以了解一下
    2021-06-06
  • C#中类与接口的区别讲解

    C#中类与接口的区别讲解

    本文详细讲解了C#中类与接口的区别,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • C# 拼图魔方小游戏

    C# 拼图魔方小游戏

    这篇文章主要介绍了C# 拼图魔方小游戏,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • C#调用WebService的方法介绍

    C#调用WebService的方法介绍

    这篇文章介绍了C#调用WebService的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03
  • C#操作config文件的具体方法

    C#操作config文件的具体方法

    这篇文章介绍了在C#中对config文件的操作,有需要的朋友可以参考一下
    2013-07-07
  • 带着问题读CLR via C#(笔记一)CLR的执行模型

    带着问题读CLR via C#(笔记一)CLR的执行模型

    CLR (Common Language Runtime) 是一个可以由多种编程语言使用的“运行时”。
    2013-04-04
  • C#检查foreach判读是否为null的方法

    C#检查foreach判读是否为null的方法

    这篇文章主要介绍了C#如何检查foreach判读其是否为null,文中给出了示例代码,介绍的很详细,需要的朋友可以参考下方法
    2016-09-09
  • C#实现获取枚举中元素个数的方法

    C#实现获取枚举中元素个数的方法

    这篇文章主要介绍了C#实现获取枚举中元素个数的方法,是深入理解C#程序设计所需要掌握的基本技巧,需要的朋友可以参考下
    2014-08-08

最新评论