【C# Programming】类、构造器、静态成员

一、类

1、类的概念

  • 类是现实世界概念的抽象:封装、继承、多态
  • 数据成员: 类中存储数据的变量
  • 成员方法: 类中操纵数据成员的函数称为成员方法
  • 对象:类的实例
  • 类定义
class X {…}      var instance = new X(…);

2、实例字段

        C#中,数据成员称为字段。与具体对象相关的字段称为实例字段;实例字段允许在声明时初始化,初始化语句在类构造函数前执行, 例如:

class Employee
{public string FirstName;public string LastName;public string Salary = "Not enough";public Employee() { Salray= string.Empty;} 
}

        实例字段只能从对象中访问,例如:

public static void Main()
{Employee employee1 = new Employee();Employee employee2;employee2 = new Employee();employee1.FirstName = "Inigo";employee1.LastName = "Montoya";employee1.Salary = "Too Little";IncreaseSalary(employee1);Console.WriteLine(  "{0} {1}: {2}",employee1.FirstName, employee1.LastName,employee1.Salary);
}
static void IncreaseSalary(Employee employee)
{employee.Salary = "Enough to survive on";
}

        C#中,  只能通过对象调用的成员方法称为实例方法。

        在类的实例成员内部,可以使用this 获得调用实例成员的对象引用,例如:

class Employee
{public string FirstName;public string LastName;public string Salary;public string GetName(){return $"{ FirstName }  { LastName }";}public void SetName(string newFirstName, string newLastName) {this.FirstName = newFirstName;this.LastName = newLastName;}
}

        this关键字也能用来显式调用实例方法 或在方法调用中传递 ,例如:

class Employee
{public string FirstName;public string LastName;public string Salary;public string GetName() => $"{ FirstName }  { LastName }";public void SetName(string newFirstName, string newLastName){this.FirstName = newFirstName;this.LastName = newLastName;Console.WriteLine( $"Name changed to '{ this.GetName() }'");}public void Save(){DataStorage.Store(this);}
}
class DataStorage
{// Save an employee object to a file named with the Employee name.public static void Store(Employee employee) { ...}
}

3、访问修饰符

访问修饰符标识了所修饰成员的封装级别。

  • public:类或成员修饰符;表明类或成员可以从类外部访问
  • private:成员修饰符; 表明修饰的成员仅在声明的类内部访问
  • protected:成员修饰符; 表明修饰的成员仅在声明的类或派生类内部访问
  • internal:类或成员修饰符;表明类或成员仅能在相同程序集内部访问
  • Protected internal:类或成员修饰符;表明类或成员仅能在当前程序集内部或派生类访问
class Employee
{public string FirstName, LastName,Salary, Password;private bool IsAuthenticated;public bool Logon(string password) {if (Password == password)IsAuthenticated = true;return IsAuthenticated;}public bool GetIsAuthenticated() => IsAuthenticated;// ...
}

4、方法的参数

        类型缺省访问级别:

Members ofDefault member accessibilityAllowed declared accessibility of the member
enumpublicNone
classprivate

public

protected

internal

private

protected internal

interfacepublicNone
structprivate

public

internal

private

5、属性

        属性结合了字段和成员方法的特点。 对于对象的用户来说,属性似乎是一个字段,访问属性使用与访问字段 相同的语法。 对于类的实现者来说,属性是由 get 访问器和/或 set 访问器组成代码块。读取属性时,执行 get 访问器的代码块;向属性赋值时,执行 set 访问器的代码块。

        不含 set 访问器的属性称为只读属性。 将不含 get 访问器的属性称为只写属性。同时具有以上两个访问器的属性称为读写属性。  

        与字段不同,属性不会被归类为变量。 因此,不能将属性作为 ref 或 out 参数传递。

6、自动实现属性

        在 C# 3.0及更高版本,当属性访问器中不需要任何其他逻辑时,自动实现的属性会使属性声明更加简洁。在 C# 6和更高版本中,可以像字段一样初始化自动实现属性。

public static void Main()
{Employee employee1 = new Employee();Employee employee2 = new Employee();employee1.FirstName = "Inigo";    // Call the FirstName property's setter.System.Console.WriteLine(employee1.FirstName);    // Call the FirstName property's getter.// Assign an auto-implemented propertyemployee2.Title = "Computer Nerd";employee1.Manager = employee2;// Print employee1's manager's title.System.Console.WriteLine(employee1.Manager.Title);
}
class Employee
{public string FirstName { get; set; }private string LastName { get; set; }public string Title { get; set; }public Employee Manager { get; set; }public string Salary { get; set; } = "Not Enough";
}

7、属性的访问限制

        缺省情况下,get /set 访问器具有相同的可见性和访问级别。从C# 2.0开始,在属性实现中允许为get 或set 部分指定访问修饰符,从而覆盖为属性指定的访问修饰符

        对属性 使用访问修饰符有以下限制:

  • 不能对接口或显式实现的接口成员使用访问修饰符。
  • 仅当属性同时包含 set 和 get 访问器时,才能使用访问器修饰符。 这种情况下,只允许对其中之一使用修饰符。
  • 如果属性或索引器具有 override 修饰符,则访问器修饰符必须与重载的访问器的访问修饰符(如有)匹配。
  • 访问器的可访问性级别必须比属性本身的可访问性级别具有更严格的限制。
class Employee
{public void Initialize(int id) => Id = id.ToString();public string Id{get { return _Id;}private set { // Providing an access modifier is possible in C# 2.0 and higher only_Id = value;}}private string _Id;
}

二、构造器

1、构造器

1.1 构造器是与类名相同,没有返回值的方法, 例如:

class Employee
{public Employee(string firstName, string lastName) // constructor{FirstName = firstName;LastName = lastName;}public string FirstName { get; set; }public string LastName { get; set; }public string  Title {get; set}public string Salary { get; set; } = "Not Enough";public string Name{get{return FirstName + " " + LastName;}set{string[] names;names = value.Split(new char[] { ' ' });if (names.Length == 2){FirstName = names[0];LastName = names[1];}else{throw new System.ArgumentException(string.Format($"Assigned value '{ value }' is invalid", nameof(value)));}}}
}

1.2 调用构造器

public static void Main()
{Employee employee;employee = new Employee("Inigo", "Montoya");employee.Salary = "Too Little";Console.WriteLine(  "{0} {1}: {2}", employee.FirstName, employee.LastName,employee.Salary);
}

1.3 默认构造器

        如果类没有显式定义构造器,C# 编译器会在编译时自动添加一个不含任何参数的构造函数。一旦类显定义构造器,编译器就不会提供默认构造函数。

2、对象初始化器

        初始化器用于初始化对象中所有可以访问的字段和属性。在调用构造器时,可以在后面的大括号中添加成员初始化列表,例如:

public static void Main()
{Employee employee = new Employee("Inigo", "Montoya"){Title = "Computer Nerd",Salary = "Not enough"};Console.WriteLine("{0} {1} ({2}): {3}", employee.FirstName, employee.LastName, employee.Title, employee.Salary);
}

3、构造器链

        C# 中,允许从一个构造器中调用同一个类的另一个构造器, 方法是在一个冒号后添加this关键字,再添加被调用构造器的参数列表,例如:

class Employee
{public Employee(string firstName, string lastName){FirstName = firstName;LastName = lastName;}public Employee(int id, string firstName, string lastName): this(firstName, lastName){Id = id;}public Employee(int id){Id = id;// NOTE: Member constructors cannot be called explicitly inline// this(id, firstName, lastName);}public int Id { get; private set; }public string FirstName { get; set; }public string LastName { get; set; }public string Salary { get; set; } = "Not Enough";
}

4、匿名类型

        匿名类型是编译器动态生成的类型,编译器遇到匿名类型时,会自动生成一个CIL类。该类具有与匿名类型声明中已经命名的值和数据类型对应的属性。例如:

public static void Main()
{var patent1 =new{Title = "Bifocals",YearOfPublication = "1784"};      var patent2 =new{Title = "Phonograph",YearOfPublication = "1877"};  var patent3 =new{patent1.Title,Year = patent1.YearOfPublication};System.Console.WriteLine("{0} ({1})",patent1.Title, patent1.YearOfPublication);System.Console.WriteLine("{0} ({1})", patent2.Title, patent1.YearOfPublication);Console.WriteLine();Console.WriteLine(patent1);Console.WriteLine(patent2);Console.WriteLine();Console.WriteLine(patent3);
}

三、静态成员

1、静态字段

        在类的多个实例之间共享的字段,用static 关键字标识。和实例字段一样,静态字段也可以在声明时初始化。例如:

class Employee
{// ...public static int  Id;   // default(int): 0 public static int NextId = 42;// ...
}

        和实例字段不一样,未初始化的静态字段将获得默认值,即 default(T)的结果

2、静态方法

        和静态字段类似,静态方法也用static关键字标识。静态方法可以通过类名直接访问。例如:

public static void Main()
{DirectoryInfo directory = new DirectoryInfo(".\\Source");directory.MoveTo(".\\Root");DirectoryInfoExtension.CopyTo(directory, ".\\Target", SearchOption.AllDirectories, "*");
}
public static class DirectoryInfoExtension
{public static void CopyTo(  DirectoryInfo sourceDirectory, string target, SearchOption option, string searchPattern) {if (target[target.Length - 1] !=  Path.DirectorySeparatorChar)target += Path.DirectorySeparatorChar;if (!Directory.Exists(target))Directory.CreateDirectory(target);for (int i = 0; i < searchPattern.Length; i++){foreach (string file in  Directory.GetFiles(sourceDirectory.FullName, searchPattern))  {File.Copy(file, target + Path.GetFileName(file), true);}}if (option == SearchOption.AllDirectories) //Copy subdirectories (recursively){foreach (string element in Directory.GetDirectories(sourceDirectory.FullName))Copy(element,  target + Path.GetFileName(element),searchPattern);}}private static void Copy(string element, string fileName, string searchPattern){Console.WriteLine("Copying " + fileName);}
}

3、静态构造器

        静态构造器不显式调用,而是在运行时在首次访问类时自动调用。首次访问类发生在条用普通构造器时,也可能发生在访问类的静态方法或字段。静态构造器不允许带任何参数

class Employee
{static Employee(){Random randomGenerator = new Random();NextId = randomGenerator.Next(101, 999);}// ...public static int NextId = 42;// ...
}

4、静态属性

        属性也能static。例如:

class Employee
{// ...public static int NextId{get{return _NextId;}private set{_NextId = value;}}public static int _NextId = 42;// ...
}

5、静态类

        C#中也能定义静态类。静态类不含任何实例字段或方法。因此静态类不能实例化。编译器自动在CIL 代码中将静态类标记为abstract 和sealed。即将类指定为不可扩展

public static class SimpleMath
{public static int Max(params int[] numbers){if (numbers.Length == 0)  // Check that there is at least one item in numbers.throw new ArgumentException( "numbers cannot be empty", nameof(numbers));int result = numbers[0]; foreach (int number in numbers){if (number > result)result = number;}return result;}
}
public class Program
{public static void Main(string[] args){int[] numbers = new int[args.Length];for (int count = 0; count < args.Length; count++)numbers[count] = args[count].Length;Console.WriteLine( $@"Longest argument length = { SimpleMath.Max(numbers) }");}
}

6、封装数据

6.1 const 字段

  • const 字段是在编译时确定的值, 在运行时不会被改变。常量字段自动成为静态字段  
  • 如果一个程序集引用了另一个程序集中的常量,常量值将直接编译进引用的程序集中
class ConvertUnits
{public const float CentimersPerInch = 2.54F; public  const int  CupsPerGallon = 16;                                                           
}

6.2 readonly

        readonly 修饰符只能用于字段(不能用于局部变量)。它指出字段值只能从构造器中更改或声明时通过初始化器更改。

class Employee
{public Employee(int id){_Id = id;}private readonly int _Id;public int Id{get { return _Id; }}// Error: A readonly field cannot be assigned to (excep in a constructor or a variable initializer)// public void SetId(int id) =>_Id = id;
}

7、分部类

        分部类是一个类的多个部分, 这些部分可以合并成一个完整的类。分部类主要用于将一个类的定义划分到多个文件中。 C# 使用关键字partial来声明分部类

// File: Program1.cs
partial class Program
{
}
// File: Program2.cs
partial class Program
{
}

8、分部方法

        分部方法存在于分部类中,它允许在一个文件中声明方法,而在另一文件中实现该方法。例如:

// File: Person.Designer.cs
public partial class Person
{#region Extensibility Method Definitionspartial void OnLastNameChanging(string value);partial void OnFirstNameChanging(string value);#endregion// ...
}
// File: Person.cs
partial class Person
{partial void OnLastNameChanging(string value){//...}partial void OnFirstNameChanging(string value){//...}
}

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

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

相关文章

图文版:以太网二层接口类型(含配套习题)

常见的以太网二层接口类型包括以下三种&#xff1a; 一、Access接口 access链路类型端口&#xff0c;一种交换机的主干道模式&#xff0c;2台交换机的2个端口之间是否能够建立干道连接&#xff0c;取决于这2个端口模式的组合。 Access端口在收到以太网帧后打开VLAN标签&#…

linux查找目录

要在Linux中查找目录&#xff0c;可以使用find命令。下面是查询目录的几个示例&#xff1a; 1,查找当前目录下所有子目录&#xff1a; find . -type d 2,在指定路径下查找目录&#xff1a; find /path/to/directory -type d 3,查找以特定名称开头的目录&#xff1a; find . -t…

前端(十七)——gitee上开源一个移动端礼盒商城项目(前端+后台)

&#x1f917;博主&#xff1a;小猫娃来啦 &#x1f917;文章核心&#xff1a;gitee上开源一个移动端礼盒商城项目 文章目录 前言开源地址项目运行命令项目基本展示前端效果细节展示视频前端代码细节展示视频后台效果展示后台代码展示经典优势思维导图实现思路 前言 项目样式老…

vue 动态绑定ref 父组件获取自组件data数据

vue中用ref 可以引用元素或组件中的数据&#xff0c;静态绑定用法非常简单&#xff0c;例如&#xff1a;this.$refs["xxx"].func() 或this.$refs["xxx"].msg 父组件调用子组件中的方法或数据。 如果在父组件中用v-for循环渲染子组件&#xff0c;并且需…

富士康曲线救国,iPhone 15 Pro订单较上代有减少,iPhone 15增加

据外媒报道&#xff0c;苹果将于9月13日凌晨举行的秋季新品发布会上推出iPhone 15系列智能手机。然而&#xff0c;令人惊讶的是&#xff0c;这款备受期待的手机在8月份就已开始批量生产&#xff0c;以确保上市初期供应充足。 随着iPhone 15系列发布时间的临近&#xff0c;越来越…

centos7 安全加固

PS&#xff1a;之前在进行安全测试的时候&#xff0c;说是报告环境有漏洞&#xff0c;于是根据报告的漏洞来查找相应的解决方案&#xff0c;当然&#xff0c;现在centos已经停止维护了&#xff0c;但是估计还是有不少使用的人&#xff0c;把他拿出来给大家一起分享一下解决方案…

Jtti:CentOS 7安装网络流量实时监控工具iftop的方法

要在CentOS 7上安装网络流量实时监控工具iftop&#xff0c;您可以按照以下步骤操作&#xff1a; 打开终端&#xff1a;在CentOS 7上&#xff0c;打开终端以执行命令。 安装EPEL存储库&#xff1a;iftop通常包含在EPEL&#xff08;Extra Packages for Enterprise Linux&#x…

怎么处理zk或redis脑裂

很极端场景会出现脑裂 什么是分布式的脑裂 怎么理解zk脑裂 就是ZK&#xff0c;与客户端可能因为网络原因&#xff0c;客户端A还在跑着后续程序&#xff0c;而zk与客户端之前的心跳断了&#xff0c;此zk就把这节点给删除了&#xff0c;这时另一个客户会加锁成功&#xff0c;就样…

CSS中如何实现文字跑马灯效果?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 跑马灯⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋…

攻防世界-WEB-php_rce

打开靶机链接 搜村ThinkPhP V5存在远程命令执行的漏洞 构建payload /index.php?sindex/think\app/invokefunction&functioncall_user_func_array&vars[0]system&vars[1][]ls 查询当前目录文件&#xff0c;没有发现flag。调整payload 得到flag文件&#xff0c;修…

Hadoop的第二个核心组件:MapReduce框架第四节

Hadoop的第二个核心组件&#xff1a;MapReduce框架 十、MapReduce的特殊应用场景1、使用MapReduce进行join操作2、使用MapReduce的计数器3、MapReduce做数据清洗 十一、MapReduce的工作流程&#xff1a;详细的工作流程第一步&#xff1a;提交MR作业资源第二步&#xff1a;运行M…

qt使用QCustomplot绘制cpu和内存使用率图

一、QCustomPlot介绍 QCustomPlot是一个开源的Qt C图表库&#xff0c;用于可视化数据。该库提供了多种类型的可定制的图表&#xff0c;包括散点图、线图、柱状图和等高线图等。它还支持自定义绘制&#xff0c;可以创建任意形状和大小的元素&#xff0c;并使其与其他元素交互。Q…

XREAL Air 2 Pro发布,加入电致变色技术,拓展AR眼镜使用场景

【2023年9月6日 中国北京】继刚刚宣布XREAL Air在全球销量突破20万台后&#xff0c;全球领先的消费级AR眼镜品牌XREAL今日于中国市场正式推出XREAL Air 2系列新品。全新Air 2系列包含两款AR眼镜产品&#xff1a;在显示、佩戴舒适性、音频等核心维度全面升级&#xff0c;体验全面…

Linux如何安装MySQL

Linux安装MySQL5.7 1、下载 官网下载地址&#xff1a;http://dev.mysql.com/downloads/mysql/ 2、复制下面几个文件 3、检查当前系统是否安装过mysql、检查当前mysql依赖环境、检查/tmp文件夹权限 1&#xff09;检查当前系统是否安装过mysql&#xff0c;执行安装命令前&am…

leetcode 20.有效括号 栈的简单应用

题目 数据结构 栈 code var isValid function(s) {// 空串和长度为奇数的字符串一定不符合要求if(!s || s.len%2){return true}let match {(: ),[: ],{: }}let stack []let len s.lengthfor(let i0; i<len; i){const ch s[i]if(ch[ || ch( || ch{){// 如果是左括号,…

London Dock丨伦敦一区的房产明星,拥揽泰晤士河美景,尽享都市奢华生活

生活在伦敦一区&#xff0c;似乎就意味跻身上流阶层 皆是精英环绕&#xff0c;也为下一代创造了极好的社区氛围 所谓“一方水土养一方人”&#xff0c;泰晤士河穿过的伦敦 也孕育着伦敦人的礼貌绅士与严谨认真。 河流&#xff0c;是城市发展的源头。 源远流长的塞纳河&…

【开发】视频集中存储/直播点播平台EasyDSS点播文件分类功能优化

视频推拉流EasyDSS视频直播点播平台&#xff0c;集视频直播、点播、转码、管理、录像、检索、时移回看等功能于一体&#xff0c;可提供音视频采集、视频推拉流、播放H.265编码视频、存储、分发等视频能力服务。 TSINGSEE青犀视频的EasyDSS平台具有点播文件分类展示方法&#xf…

SpringBoot项目整合RabbitMQ

1. 简介 消息队列&#xff08;Message Queue&#xff09;是分布式系统中常用的组件&#xff0c;它允许不同的应用程序之间通过发送和接收消息进行通信。Spring Boot提供了简单且强大的方式来整合消息队列&#xff0c;其中包括RabbitMQ、ActiveMQ、Kafka等多种消息队列实现。 …

awtk-ftpd 发布

1. 介绍 在嵌入式应用程序中&#xff0c;有时需要提供一个 FTP 服务&#xff0c;用于对系统的文件进行远程管理。 awtk-ftpd 实现了一个 简单的 FTP 服务。主要特色有&#xff1a; 小巧。约 800 行代码。可以在各种嵌入式平台运行。内存开销低。正常内存需求小于 6K。兼容 F…

蓝桥杯备赛Day7——算法复杂度分析、前缀和思想

O(nlogn)算法可能达到的最优复杂度。快速排序算法是典型例子。 O(n^2)一个两重循环的算法,复杂度是O(n^2)。例如冒泡排序,是典型的两重循环。 O(n^3)、O(n^4)等等。 O(2n)一般对应集合问题。 例如一个集合中有n个数,要求输出它的所有子集。 O(n!)在集合问题中,如果要求按顺…