C# 属性与结构

C# 属性

C# 属性,属性是一种特殊的类成员。 我们使用预定义的 set 和 get 方法来访问和修改它们。 属性读取和写入会转换为获取和设置方法调用。 与使用自定义方法调用(例如object.GetName())相比,使用字段符号(例如object.Name)访问变量更容易。 但是,就属性而言,我们仍然具有封装和信息隐藏的优势。 换句话说,属性可以保护数据免受外界干扰,同时可以方便地进行现场访问。

接口可以具有属性,但不能具有字段。

属性可以是读写的(它们既有 get 和 set 访问器),也可以是只读的(它们只有 get 访问器)或只写(它们只有 set 访问器)。

Program.
using System;namespace SimpleProperties
{class Person{private string _name;public string Name{get { return _name; }set { _name = value; }}}class Program{static void Main(string[] args){var p = new Person();p.Name = "Jane";Console.WriteLine(p.Name);}}
}

我们有一个具有一个属性的简单 Person 类。

public string Name
{...
}

我们有一个称为Name的属性。 它看起来像一个常规方法声明。 不同之处在于,它具有称为getset的特定访问器。

get { return _name; }
set { _name = value; } 

get属性访问器用于返回属性值,set访问器用于分配新值。 value关键字用于定义由设置索引器分配的值。

var p = new Person();
p.Name = "Jane";Console.WriteLine(p.Name);

我们创建Person类的实例。 我们使用字段符号访问成员字段。

$ dotnet run
Jane

这是该计划的结果。

C# 只读属性

可以创建只读属性。 为了创建一个只读属性,我们省略了 set 访问器,在实现中仅提供了 get 访问器。

Program.
using System;namespace Readonly
{class Person{private string _name = "Jane";public string Name{get { return _name; }}}class Program{static void Main(string[] args){var p = new Person();// p.Name = "Beky";Console.WriteLine(p.Name);}}
}

在前面的示例中,我们演示了只读属性的使用。

private string _name = "Jane";

我们立即初始化成员,因为以后不可能。

public string Name
{get { return _name; }
}

通过仅提供一个 get 访问器,使该属性为只读。

// p.Name = "Beky";

现在此行已注释。 我们无法更改属性。 如果我们取消注释该行,则 C# 编译器将发出以下错误:Program.(21,13): error 0200: Property or indexer 'Person.Name' cannot be assigned to -- it is read only

C# 自动实现的属性

C# 具有自动实现或自动属性。 在软件项目中,有许多简单属性只能设置或获取一些简单值。 为了简化编程并简化代码,创建了自动属性。 注意,我们不能在所有情况下都使用自动属性。 仅适用于简单的。

Program.
using System;namespace Autoimplemented
{class Person{public string Name { get; set; }public int Age { get; set; }}class Program{static void Main(string[] args){var p = new Person();p.Name = "Jane";p.Age = 17;Console.WriteLine($"{p.Name} is {p.Age} years old");}}
}    

该代码要短得多。 我们有一个Person类,其中有两个属性:NameAge

public string Name { get; set; }
public int Age { get; set; }

在这里,我们有两个自动属性。 没有访问器的实现,也没有成员字段。 编译器将为我们完成其余的工作。

var p = new Person();
p.Name = "Jane";
p.Age = 17;Console.WriteLine($"{p.Name} is {p.Age} years old");

我们通常照常使用这些属性。

$ dotnet run
Jane is 17 years old

这是示例的输出。

表达式主体定义

从 C# 7.0 开始,可以使用表达式主体定义简化属性。 表达式主体定义由=>符号组成,后跟要分配给该属性或从该属性检索的表达式。

Program.
using System;namespace ExpBodyDef
{class User{string name;string occupation;public User(string name, string occupation){this.name = name;this.occupation = occupation;}public string Name{get => name;set => name = value;}public string Occupation{get => occupation;set => occupation = value;}}class Program{static void Main(string[] args){var u = new User("John Doe", "gardener");Console.WriteLine($"{u.Name} is a {u.Occupation}");}}
}

在示例中,我们使用表达式主体定义来定义User类的属性。

$ dotnet run
John Doe is a gardener

这是输出。

其他注意事项

我们可以使用publicprivateprotected等访问修饰符标记属性。 属性也可以是staticabstractvirtualsealed。 它们的用法与常规方法相同。

Program.
using System;namespace OtherNotes
{class Base{protected string _name = "Base class";public virtual string Name{set { _name = value; }get { return _name; }}}class Derived : Base{protected new string _name = "Derived class";public override string Name{set { _name = value; }get { return _name; }}}class Program{static void Main(string[] args){var bs = new Base();var dr = new Derived();Console.WriteLine(bs.Name);Console.WriteLine(dr.Name);}}
}

在前面的示例中,我们定义了一个虚拟属性,并在Derived类中将其覆盖。

public virtual string Name
{set { _name = value; }get { return _name; }
}

名称属性用virtual关键字标记。

protected new string _name = "Derived class"; 

我们将成员隐藏在“派生”类中。 为了消除编译器警告,我们使用new关键字。

public override string Name
{set { _name = value; }get { return _name; }
}

在这里,我们重写了Base类的Name属性。

结构 (程序优化)

C# 结构,结构是值类型。 该类型由struct关键字定义。 结构与类非常相似。 它们在某些方面有所不同。 结构旨在表示轻量级对象,例如PointRectangleColor等。 在许多情况下,结构可能比类更有效。 结构是值类型,并在堆栈上创建。 注意,像intboolfloat之类的原始数据类型在技术上都是struct类型。

所有struct类型都继承自System.ValueType,并且继承自System.Object。 结构从来都不是抽象的,它们总是被隐式密封的。 因此结构类型不支持继承。 因此,不能将struct数据成员声明为受保护的。 struct定义不允许使用抽象修饰符和密封修饰符。 不允许struct声明无参数的构造函数。

结构还可以包含构造函数,常量,字段,方法,属性,索引器,运算符,事件和嵌套类型。 但是,如果我们需要实现更多这些功能,则可以考虑使用一个类。 结构可以实现接口。 struct可以用作nullable类型,并且可以分配为空值。

简单结构示例

以下示例创建一个简单的结构。

Program.
using System;namespace SimpleStructure
{public struct Point{private int x;private int y;public Point(int x, int y){this.x = x;this.y = y;}public override string ToString(){return String.Format("Point x:{0}, y:{1}", x, y);}}class Program{static void Main(string[] args){var p = new Point(2, 5);Console.WriteLine(p);}}
}

该示例创建一个Point结构。 这个点也可以用一个类来表示,但是有了struct,我们的效率更高了。 特别是如果我们处理了很多问题。

public struct Point
{...
}

该结构用struct关键字声明。

public override string ToString()
{return String.Format("Point x:{0}, y:{1}", x, y);
}

struct类型不支持继承。 但是,我们可以对方法使用override关键字,struct类型隐式地从中继承。 ToString()方法就是这种情况。

var p = new Point(2, 5);
Console.WriteLine(p);

我们创建Point结构,并在其上调用ToString()方法。

$ dotnet run
Point x:2, y:5

这是示例的输出。

没有new关键字

可以创建不带new关键字的struct类型的实例。

Program.
using System;namespace NoNewKeyword
{public struct Person{public string name;public int age;}class Program{static void Main(string[] args){Person p;p.name = "Jane";p.age = 17;Console.WriteLine("{0} is {1} years old",p.name, p.age);}}
}

我们有一个Person结构,其中有两个公共成员。

Person p;

首先,我们声明一个Person结构。

p.name = "Jane";
p.age = 17;

稍后我们用一些数据初始化结构。

$ dotnet run
Jane is 17 years old

这是程序的输出。

C# 结构是值类型

结构类型是值类型。 它们是在堆栈上创建的。 创建值类型时,仅在内存中分配了一个空间来存储值。 值类型的分配将复制该值。

Program.
using System;namespace ValueTypes
{public struct Person{public Person(string name, int age) : this(){this.Name = name;this.Age = age;}public string Name { get; set; }public int Age { get; set; }public override string ToString(){return String.Format("{0} is {1} years old", Name, Age);}}class Program{static void Main(string[] args){var p1 = new Person("Beky", 18);var p2 = p1;Console.WriteLine(p2);p2.Name = "Jane";p2.Age = 17;Console.WriteLine(p2);Console.WriteLine(p1);}}
}

我们有一个带有两个数据成员的Person结构。 我们有两个参数的构造函数,我们也使用自动属性。

public string Name { get; set; }
public int Age { get; set; }

可以在struct类型中使用自动属性。

var p1 = new Person("Beky", 18);
var p2 = p1;

在这里,我们创建一个struct。 然后将创建的struct分配给另一个struct。 我们创建该结构的副本。

p2.Name = "Jane";
p2.Age = 17;

我们更改第二个结构的数据。 第一个不受影响,因为我们正在处理原始struct类型的副本。

$ dotnet run
Beky is 18 years old
Jane is 17 years old
Beky is 18 years old

基本类型是结构

intfloatbool之类的原始数据类型是内部结构。 这不同于 C++ 或 Java 之类的语言。

Program.
using System;public class PrimitiveTypes
{static void Main(){float x = 12.3f;int y = 34;bool z = false;Console.WriteLine(x.GetType());Console.WriteLine(y.GetType());Console.WriteLine(z.GetType());}
}

我们有三个变量:float,intbool。 我们对它们每个调用GetType()方法。

Console.WriteLine(x.GetType());

我们在浮点值上调用GetType()方法。 每个结构都隐式继承自包含GetType()方法的System.ValueType类。

$ dotnet run
System.Single
System.Int32
System.Boolean

这是示例的输出。 我们可以在文档中查找这些类型是结构。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/60016.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

视频里的音频怎么提取出来成单独文件?音频提取照着这些方法做

在数字时代,视频与音频的分离与重组已成为日常需求之一。无论是出于制作背景音乐、保存讲座内容,还是编辑播客素材,提取视频中的音频并将其保存为单独文件都显得尤为重要。视频里的音频怎么提取出来成单独文件?本文将详细介绍几种…

React(一)

文章目录 项目地址一、创建第一个react项目二、JSX语法2.1 生成列表2.2 大括号识别JS的表达式2.3 列表循环array2.4 条件判断以及假值显示2.5 复杂条件渲染2.6 事件监听和绑定2.7 使用Fregments返回多个根标签2.8 多条件渲染2.9 导出子组件 三、组件3.1 设置组件3.2 props给子组…

记录一下在原有的接口中增加文件上传☞@RequestPart

首先,咱声明一下: RequestBody和 MultipartFile 不可以 同时使用!!! 因为这两者预期的请求内容类型不同。RequestBody 预期请求的 Content-Type 是 application/json 或 application/xml,而 MultipartFile …

HTTPSOK ---助力阿里云免费 SSL 证书自动续期

目前许多用户面临着 SSL 证书过期续期的难题,尤其是对于阿里云的 免费 SSL 证书,每三个月需要手动申请和更新。为了帮助用户更轻松地管理 SSL 证书,现推出了强大的 HTTPSOK 服务,为用户提供了更便捷的自动续期和管理解决方案。 什…

5G的SUCI、SUPI、5G-GUTI使用场景及关系

使用场景(来源于对23.501、23.502、33.501、23.003的理解) 1、UE初始注册时,根据HN Public Key把SUPI加密成SUCI,并发送初始注册请求 2、AMF转发SUCI给AUSF和UDM进行认证,并获取解密后的SUPI 3、AMF根据SUPI生成一个5G-GUTI,并保…

大数据-226 离线数仓 - Flume 优化配置 自定义拦截器 拦截原理 拦截器实现 Java

点一下关注吧!!!非常感谢!!持续更新!!! Java篇开始了! 目前开始更新 MyBatis,一起深入浅出! 目前已经更新到了: Hadoop&#xff0…

PyAEDT:Ansys Electronics Desktop API 简介

在本文中,我将向您介绍 PyAEDT,这是一个 Python 库,旨在增强您对 Ansys Electronics Desktop 或 AEDT 的体验。PyAEDT 通过直接与 AEDT API 交互来简化脚本编写,从而允许在 Ansys 的电磁、热和机械求解器套件之间无缝集成。通过利…

定时器(QTimer)与随机数生成器(QRandomGenerator)的应用实践——Qt(C++)

一、QTimer与QRandomGenerator (一)QTimer(定时器)[2] QTimer类为定时功能提供了一个高级编程接口。在使用QTimer时,实例化一个QTimer对象并将其timeout()发射信号与合适的信号槽相连接。通过调用QTimer的start()函数…

用redis的zset实现日榜,周榜,月榜

思路&#xff1a; 1.初始化一个月的数据&#xff1a; /*** 初始化一个月数据*/Testpublic void initMonthData(){//计算当前时间小时的keylong hourSystem.currentTimeMillis()/(1000*60*60);for(int i1;i<24*30;i){String key"W_hour"(hour-i);Random random new…

通过shell脚本分析部署nginx网络服务

通过shell脚本分析部署nginx网络服务 1.接收用户部署的服务名称 [rootlocalhost xzy]# vim 1.sh [rootlocalhost xzy]# chmod x 1.sh [rootlocalhost xzy]# ./1.sh2.判断服务是否安装 已安装&#xff1b;自定义网站配置路径为/www&#xff1b;并创建共享目录和网页文件&…

威胁驱动的网络安全方法论

摘要 目前的网络安全风险管理实践很大程度上是由合规性要求驱动的&#xff0c;这使得公司/组织不得不在安全控制和漏洞上投入人力/物力。&#xff08;风险管理涉及多个方面&#xff0c;包括资产、威胁、漏洞和控制&#xff0c;并根据事故发生的可能性及造成的影响进行评估。威…

『VUE』30. 生命周期的介绍(详细图文注释)

目录 生命周期生命周期的8阶段生命周期小例子总结 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 生命周期 每个 Vue 组件实例在创建时都需要经历一系列的初始化步骤&#xff0c;比如设置好数据侦听&#xff0c;编译模板&#xf…

idea 通过git撤销commit但未push的操作

1、undo commit 适用情况&#xff1a;代码修改完了&#xff0c;已经Commit了&#xff0c;但是还未push&#xff0c;然后发现还有地方需要修改不想提交本次记录了。这时可以进行Undo Commit&#xff0c;修改后再重新Commit。注意&#xff1a;如果已经进行了Push&#xff0c;线上…

【graphics】图形绘制 C++

众所周知&#xff0c;周知所众&#xff0c;图形绘制对于竞赛学僧毫无用处&#xff0c;所以这个文章&#xff0c;专门对相关人员教学&#xff08;成长中的码农、高中僧、大学僧&#xff09;。 他人经验教学参考https://blog.csdn.net/qq_46107892/article/details/133386358?o…

Spring Boot出现java: 错误: 无效的源发行版:16的解决方式

第一步&#xff1a; 修改为SDK的目标字节码版本 第二步&#xff1a;CtrlShiftAltS进入项目结构 第三步&#xff1a;pom.xml文件中 在网上搜索和自己SDK适配的Springboot版本&#xff0c;1.8对应的是2.7.1&#xff08;可以用&#xff09; 修改Java版本为1.8 最后的最后&a…

FPGA 第6讲 简单组合逻辑多路选择器

时间&#xff1a;2024.11.11-11.14 一、学习内容 1.组合逻辑 组合逻辑是VerilgHDL设计中一个重要组成部分。从电路本质上讲&#xff0c;组合逻辑电路的特点是输出信号只是当前时刻输入信号的函数&#xff0c;与其他时刻的输入状态无关&#xff0c;无存储电路&#xff0c;也没…

【C++初阶】C++入门

1、C第一个程序 C是脱胎于C语言的&#xff0c;所以也包含了C语言绝大多数的内容&#xff0c;C兼容C语言绝大多数的语法,在C语言中能实现的程序在C中也是可以执行的&#xff0c;但需要将定义文件代码的后缀改为.cpp 就比如hello world程序 // test.cpp #include<stdio.h&g…

selenium元素定位校验以及遇到的元素操作问题记录

页面元素定位方法及校验 使用比较多的是通过id、class和xpath来对元素进行定位。在定位前可以现在浏览器验证是否可以找到指定的元素。这样就不用每添加一个元素定位都运行代码来检查定位方式表达式是否正确。 使用XPATH定位 在浏览器F12&#xff0c;找到元素&#xff0c;在元…

网络安全之国际主流网络安全架构模型

目前&#xff0c;国际主流的网络安全架构模型主要有&#xff1a; ● 信息技术咨询公司Gartner的ASA&#xff08;Adaptive Security Architecture自适应安全架构&#xff09; ● 美国政府资助的非营利研究机构MITRE的ATT&CK&#xff08;Adversarial Tactics Techniques &…

CC工具箱使用指南:【CAD导出界址点Excel】

一、简介 群友定制工具。 面图层导出界址点Excel表之前已经做过好几个&#xff0c;这个工具则是将CAD导出Excel。 CAD数据如下&#xff1a; 工具将如上截图中的边界线导出界址点Excel&#xff0c;并记录下面内的文字。 二、工具参数介绍 点击【定制工具】组里的【CAD导出界…