热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

浅析C#结构体struct

这篇文章主要介绍了C#结构体struct的相关资料,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下

结构体

有时候我们仅需要一个小的数据结构,类提供的功能多于我们需要的功能;考虑到性能原因,最好使用结构体。

结构体是值类型,存储在栈中或存储为内联(如果结构体是存储在堆中的另一个对象的一部分)。

例如类class:

public class Dimensions
{
  public Dimensions(double length, double width)
  {
    Length = length;
    Width = width;
  }
  public double Length { get; set; }
  public double Width { get; set; }
}

可以使用结构体struct替换:

public struct Dimensions
{
  public Dimensions(double length, double width)
  {
    Length = length;
    Width = width;
  }
  public double Length { get; set; }
  public double Width { get; set; }
}

也可以为结构体struct创建函数,和给类创建函数完全相同:

public struct Dimensions
{
  public Dimensions(double length, double width)
  {
    Length = length;
    Width = width;
  }
  public double Length { get; set; }
  public double Width { get; set; }
  public double DiagOnal=> Math.Sqrt(Length * Length + Width * Width);
}

结构体初始化

结构体是值类型,但在使用时的语法和类基本一模一样。例如对于上面定义的类或结构体,均可使用代码:

Dimensions point = new Dimensions(3, 6);

注意:

因为结构体是值类型,所以new运算符与类和其他引用类型的工作方式不同。

用于结构体struct的new运算符并不分配堆中的内存,而是只调用相应的构造函数,根据传送给它的参数,初始化所有字段。

对于结构,变量声明实际上是韦整个结构在栈中分配空间。例如用如下语法(如果是类的话,就会编译错误):

Dimensions point; //直接省略new
point.Length = 3;
point.Width = 6;

结构体遵循其他数据类型都遵守的规则:在使用前所有元素都必须进行初始化。

结构体的初始化方法:

  • 使用new运算符
  • 给所有的字段直接赋值

结构体性能影响

  • 为结构体分配内存时,速度非常快,因为它们将内联或者保存在栈中。结构体超出作用域被删除时,速度也很快,不需要等待垃圾收集。
  • 如果把结构体作为参数来传递,或者把一个结构体赋值给另一个结构体,结构体的所有内容就会被复制;这样就会有性能损失。这也是为什么结构体主要用于小的数据结构。
  • 把结构体作为参数传递给方法时,应该把它作为ref参数传递 - 此时只传递了结构体在内存中地址。

只读结构体

C#7.2开始,readonly修饰符可以应用于结构体struct,因此编译器保证结构体的不变性。

public readonly struct Dimensions
{
  public Dimensions(double length, double width)
  {
    Length = length;
    Width = width;
  }
  public double Length { get; }
  public double Width { get; }
  public double DiagOnal=> Math.Sqrt(Length * Length + Width * Width);
}

对于readonly修饰符,如果在创建对象后类型更改了字段或属性,编译器就会报错。

使用readonly编译器可以生成优化的代码,使其在传递结构体时不会复制结构体的内容;

相反,编译器使用引用,因为它永远不会改变。

注意:上面readonly结构体的属性是只读的,只有get;如果有set的话,编译会报错:

error CS8341: Auto-implemented instance properties in readonly structs must be readonly.

结构体和类 - 值类型和引用类型

using System;
 
namespace value_reference
{
 
  public struct A
  {
    public int x { get; set; }
  }
 
  public class B
  {
    public int x { get; set; }
  }
 
  class Program
  {
    public static void UpdateStructValue(A a)
    {
      a.x = 10;
    }
 
    public static void UpdateObjectValue(B b)
    {
      b.x = 10;
    }
 
    static void Main(string[] args)
    {
      var a = new A { x = 1 };
      var b = new B { x = 1 };
 
      UpdateStructValue(a);
      UpdateObjectValue(b);
 
      Console.WriteLine($"a.x -> {a.x}");
      Console.WriteLine($"b.x -> {b.x}");
    }
  }
}

输出结果:

$ dotnet run
a.x -> 1
b.x -> 10

以上就是浅析C# 结构体struct 的详细内容,更多关于C# 结构体struct 的资料请关注其它相关文章!


推荐阅读
  • switch语句的一些用法及注意事项
    本文介绍了使用switch语句时的一些用法和注意事项,包括如何实现"fall through"、default语句的作用、在case语句中定义变量时可能出现的问题以及解决方法。同时也提到了C#严格控制switch分支不允许贯穿的规定。通过本文的介绍,读者可以更好地理解和使用switch语句。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • 解决VS写C#项目导入MySQL数据源报错“You have a usable connection already”问题的正确方法
    本文介绍了在VS写C#项目导入MySQL数据源时出现报错“You have a usable connection already”的问题,并给出了正确的解决方法。详细描述了问题的出现情况和报错信息,并提供了解决该问题的步骤和注意事项。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • ASP.NET2.0数据教程之十四:使用FormView的模板
    本文介绍了在ASP.NET 2.0中使用FormView控件来实现自定义的显示外观,与GridView和DetailsView不同,FormView使用模板来呈现,可以实现不规则的外观呈现。同时还介绍了TemplateField的用法和FormView与DetailsView的区别。 ... [详细]
  • C# WPF自定义按钮的方法
    本文介绍了在C# WPF中实现自定义按钮的方法,包括使用图片作为按钮背景、自定义鼠标进入效果、自定义按压效果和自定义禁用效果。通过创建CustomButton.cs类和ButtonStyles.xaml资源文件,设计按钮的Style并添加所需的依赖属性,可以实现自定义按钮的效果。示例代码在ButtonStyles.xaml中给出。 ... [详细]
  • 摘要: 在测试数据中,生成中文姓名是一个常见的需求。本文介绍了使用C#编写的随机生成中文姓名的方法,并分享了相关代码。作者欢迎读者提出意见和建议。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • 导出功能protectedvoidbtnExport(objectsender,EventArgse){用来打开下载窗口stringfileName中 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 本文是关于C#类型系统、值类型和引用类型的概念性笔记。介绍了C#1系统类型的三个特性,静态类型的含义,显式类型和隐式类型的区别。还讨论了类、结构、数组类型、枚举、委托类型和接口类型属于哪一种类型。同时纠正了关于结构、引用类型和对象传递的错误表述。最后提到了C#4中使用动态类型的关键字。 ... [详细]
  • HTML5网页模板怎么加百度统计?
    本文介绍了如何在HTML5网页模板中加入百度统计,并对模板文件、css样式表、js插件库等内容进行了说明。同时还解答了关于HTML5网页模板的使用方法、表单提交、域名和空间的问题,并介绍了如何使用Visual Studio 2010创建HTML5模板。此外,还提到了使用Jquery编写美好的HTML5前端框架模板的方法,以及制作企业HTML5网站模板和支持HTML5的CMS。 ... [详细]
  • JavaScript简介及语言特点
    本文介绍了JavaScript的起源和发展历程,以及其在前端验证和服务器端开发中的应用。同时,还介绍了ECMAScript标准、DOM对象和BOM对象的作用及特点。最后,对JavaScript作为解释型语言和编译型语言的区别进行了说明。 ... [详细]
author-avatar
你说的白是小白的白_958
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有