前言
在AI教我学编程之C#类型中,我们学习了C#类型的的基础知识,而类
正是类型
的一种.
目录
区分类和类型
在 C# 中,类是类型的一种。C# 是一种面向对象的编程语言,它的类型系统分为值类型和引用类型。类属于引用类型的范畴,因为它是用户定义的引用类型。
什么是类?
或者说,什么样的构造可以称之为类?
在菜鸟教程上我们可以看到这段话
我们来看看AI对此会如何回答?
对话AI
什么样的构造可以称之为类?
在面向对象编程中,一个类是一个用于创建对象的蓝图或模板。一个类可以包含以下元素:
-
成员变量(字段): 用于存储对象的状态或属性。
csharpclass Person { // 成员变量 public string Name; public int Age; }
-
成员方法: 用于定义对象的行为或操作。
csharpclass Person { // 成员方法 public void DisplayInfo() { Console.WriteLine($"Name: {Name}, Age: {Age}"); } }
-
构造函数: 用于初始化对象的特定状态。
csharpclass Person { // 成员变量 public string Name; public int Age; // 构造函数 public Person(string name, int age) { Name = name; Age = age; } }
-
属性(可选): 提供对成员变量的访问和修改的公共接口。
csharpclass Person { // 自动属性 public string Name { get; set; } public int Age { get; set; } }
-
事件(可选): 允许对象发布和订阅事件。
csharpclass Button { // 事件 public event EventHandler Click; // 触发事件的方法 protected virtual void OnClick(EventArgs e) { Click?.Invoke(this, e); } }
一个类的目的是封装数据和行为,通过创建对象的实例来使用这些数据和行为。上述元素的组合形成了一个完整的类定义。在使用类时,你可以实例化它并调用其中的方法,访问或修改成员变量等。
首先我们看到这几段代码都以class关键字作为开始,就是说,这段代码表示
类
是由class
关键字开始,名称为person
,由以下三个元素组成
- 成员变量:
Name
:用于存储人员的名字。Age
:用于存储人员的年龄。
- 构造函数:
public Person(string name, int age)
:构造函数用于在创建Person
类的实例时初始化对象的状态(名字和年龄)。 - 成员方法:
DisplayInfo()
:成员方法用于显示人员的名字和年龄信息。
那么剩下两个
可选项
是做什么的呢?我们接着往下看
追问
你刚刚列出了两个可选项,属性和事件,为什么这两个只是可选项?
属性和事件在类的设计中是可选的,而不是必需的,这取决于你的设计需求。下面是关于为什么它们是可选项的一些解释:
-
属性(Properties):
- 作用: 属性提供了一种用于访问和修改类的成员变量的公共接口。它们允许你在读取或写入属性值时执行逻辑,并且可以隐藏实际的字段实现。
- 为何是可选: 有时,一个简单的公共字段足以满足类的需求,而不需要额外的逻辑。在这种情况下,你可以选择跳过属性的使用。
csharpclass Person { // 公共字段 public string Name; public int Age; }
或者使用属性:
csharpclass Person { // 属性 public string Name { get; set; } public int Age { get; set; } }
-
事件(Events):
- 作用: 事件允许类发布和订阅特定的行为,通常与异步编程和观察者模式有关。
- 为何是可选: 如果你的类不需要定义或响应外部的事件,那么你可以省略事件的使用。事件通常在需要处理异步或交互式操作时使用,而在其他情况下可能不是必需的。
csharpclass Button { // 事件 public event EventHandler Click; // 触发事件的方法 protected virtual void OnClick(EventArgs e) { Click?.Invoke(this, e); } }
因此,可选性提供了灵活性,使得类的设计能够根据具体需求进行调整,而不必强制要求每个类都具有属性和事件。
为更加直观理解这两个概念,我们来实操一下
实操
1、打开Visual Studio (我的是2010,在这里就用2010来演示)
2、新建项目
3、模板选择visual C# Windows---> Windows窗体应用
4、起好名后进入以下页面
提示
:千万别忘了**命名规范**哦!
5、点击左侧边栏工具箱
6、我们看到工具箱把窗体覆盖住了
7、不用担心,点击工具箱右上角的倒三角,选择停靠
,这样就可以正常显示了
8、选择工具箱中的工作控件"按钮",拖动到窗体上
9、右击按钮,选择属性,我们可以在右下角看到属性栏
此时,不管我们拖动什么控件到窗体中,单击控件或者窗体,即可看它的属性
让我们回到刚刚的问题,为什么属性
和事件
是可选
的?
AI的回答是:在不需要额外逻辑的情况下,可以跳过属性的使用
追踪属性的使用
1、双击按钮进入如下页面
AI登场
以上这段代码中,有个按钮,我需要根据这段代码实现点击按钮跳出"青青草原我最狂,舍我其谁懒大王!"的提示文字
要在点击按钮时弹出提示文字,你需要在 button1_Click 事件处理方法中添加相应的代码。以下是修改后的代码:
haskell
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace FirstProject
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// 在按钮点击事件中添加代码
MessageBox.Show("青青草原我最狂,舍我其谁懒大王!");
}
}
}
在这个修改后的代码中,当 button1 被点击时,button1_Click 事件处理方法会弹出一个消息框(MessageBox),显示指定的提示文字。 MessageBox.Show 方法用于在 Windows 窗体应用程序中显示一个简单的消息框。
如下图所示,点击debug旁边的绿色三角开启调试
画面左上角我们看到,项目正在运行
点击按钮,跳出提示
逐步推进
现在我需要你在代码中添加类的属性的使用
haskell
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace FirstProject
{
public partial class Form1 : Form
{
// 新增的属性
public string Name { get; set; }
public int Age { get; set; }
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// 在按钮点击事件中使用属性
Name = "青青草原我最狂";
Age = 25;
// 弹出消息框显示属性值
MessageBox.Show($"姓名:{Name}\n年龄:{Age}\n舍我其谁懒大王!");
}
}
}
在这个示例中,我添加了两个属性
Name
和Age
,并在按钮点击事件中给它们赋值。然后,通过MessageBox.Show
方法显示属性的值。这个例子演示了如何在类中使用属性,以便存储和获取对象的状态。
提出疑问
这段代码中属性的使用是必须的吗?
在给定的代码示例中,属性的使用并不是必需的。在C#中,属性是用于封装对象的状态并提供对其进行访问和修改的公共接口的一种方式。在一些情况下,你可能不需要使用属性,尤其是当类的成员变量(字段)可以直接访问而不需要额外的逻辑时。
在给定的代码示例中,如果你只是在按钮点击事件中使用了一次 Name 和 Age,并且没有其他需要对这些值进行封装或加入逻辑的地方,那么使用属性是可选的。你可以直接在 button1_Click 事件中声明局部变量来存储这些值,而无需将它们定义为属性。
以下是示例,演示如何在不使用属性的情况下直接声明并使用局部变量:
haskell
using System;
using System.Windows.Forms;
namespace FirstProject
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// 直接声明和使用局部变量
string name = "青青草原我最狂";
int age = 25;
// 弹出消息框显示变量值
MessageBox.Show($"姓名:{name}\n年龄:{age}\n舍我其谁懒大王!");
}
}
}
在这个例子中,我直接在 button1_Click 事件中声明了局部变量 name 和 age,并使用它们存储和显示信息,而没有使用属性。
药不能停
紧接着我补充道
我需要你添加的是必需的属性,根据原有代码重新添加
如果你希望使用属性,我会在代码中重新添加必需的属性。以下是在原有代码基础上添加必需的属性的修改版本:
haskell
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace FirstProject
{
public partial class Form1 : Form
{
// 必需的属性
public string Name { get; set; }
public int Age { get; set; }
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// 在按钮点击事件中使用属性
Name = "青青草原我最狂";
Age = 25;
// 弹出消息框显示属性值
MessageBox.Show($"姓名:{Name}\n年龄:{Age}\n舍我其谁懒大王!");
}
}
}
在这个修改后的代码中,我添加了两个名为 Name 和 Age 的属性。这样,你可以在类的其他地方使用这些属性,而不仅仅是在 button1_Click 事件中。这种封装的方式提高了代码的可维护性和灵活性。
终于实现
根据现有代码写两段代码,第一段代码即原代码,另一段代码则必须使用属性才能实现其逻辑和功能
代码段一:不使用属性,直接声明并使用局部变量
csharp
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace FirstProject
{
public partial class Form1 : Form
{
// 必需的属性
public string Name { get; set; }
public int Age { get; set; }
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// 在按钮点击事件中使用属性
Name = "青青草原我最狂";
Age = 25;
// 弹出消息框显示属性值
MessageBox.Show($"姓名:{Name}\n年龄:{Age}\n舍我其谁懒大王!");
}
}
}
代码段二:使用属性实现逻辑和功能
在这个示例中,我添加了一些逻辑和功能,并使用属性来存储和访问数据:
csharp
using System;
using System.Windows.Forms;
namespace FirstProject
{
public partial class Form1 : Form
{
// 使用属性
public string Name { get; set; }
public int Age { get; set; }
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// 使用属性存储数据
Name = "青青草原我最狂";
Age = 25;
// 调用带有逻辑的方法
DisplayInfo();
// 弹出消息框显示属性值
MessageBox.Show($"姓名:{Name}\n年龄:{Age}\n舍我其谁懒大王!");
}
// 带有逻辑的方法
private void DisplayInfo()
{
Console.WriteLine($"在 DisplayInfo 方法中:姓名:{Name},年龄:{Age}");
// 可以在这里添加更多的逻辑和功能
}
}
}
在这个示例中,button1_Click
事件使用属性 Name
和 Age
存储数据,然后调用了一个带有逻辑的方法 DisplayInfo
。在这个方法中,你可以添加更多的逻辑和功能。这种方式充分利用了属性的封装性,使得逻辑更加清晰和可维护。
这里的DisplayInfo
方法,就是AI刚刚提到的可以填充额外的逻辑
的地方
探索事件的使用
异步/交互操作
我现在需要在原代码中可以"处理异步或交互式操作",据此要求完善代码
如果你想要在原有代码中处理异步或交互式操作,可以使用异步方法和
async
/await
关键字。下面是对原有代码的修改,使其能够处理异步操作:
csharp
using System;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FirstProject
{
public partial class Form1 : Form
{
// 使用属性
public string Name { get; set; }
public int Age { get; set; }
public Form1()
{
InitializeComponent();
}
private async void button1_Click(object sender, EventArgs e)
{
// 使用属性存储数据
Name = "青青草原我最狂";
Age = 25;
// 异步操作
await DisplayInfoAsync();
// 弹出消息框显示属性值
MessageBox.Show($"姓名:{Name}\n年龄:{Age}\n舍我其谁懒大王!");
}
// 异步方法
private async Task DisplayInfoAsync()
{
// 异步操作,模拟耗时操作
await Task.Delay(2000);
// 在异步方法中使用属性
Console.WriteLine($"在 DisplayInfoAsync 方法中:姓名:{Name},年龄:{Age}");
// 可以在这里添加更多的异步操作
}
}
}
在这个示例中,我将 DisplayInfo
方法改为 DisplayInfoAsync
,并在其内部添加了一个异步操作 await Task.Delay(2000)
以模拟耗时操作。同时,button1_Click
事件也被标记为 async
,并在其中使用了 await
关键字来等待异步方法的完成。这样,你可以在异步方法中执行可能涉及等待的耗时操作,而不会阻塞主线程。
耗时操作
在你刚才给出的代码中,可以执行哪些"耗时操作",告诉我,并且将这个操作添加到代码中,使我在调试时可以明显的看到"耗时"这一效果
在我之前提供的代码示例中,我添加了一个模拟耗时操作的异步方法
DisplayInfoAsync
,其中使用了await Task.Delay(2000)
来模拟一个持续两秒的异步操作。这个延迟操作是一个简单的例子,用来模拟可能的耗时操作。
在实际的应用中,你可以将异步方法中的 Task.Delay
替换为真实的耗时操作,比如从数据库中读取数据、进行网络请求、进行复杂的计算等。以下是对代码的修改,其中包含了一个更具体的耗时操作示例:
csharp
using System;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FirstProject
{
public partial class Form1 : Form
{
// 使用属性
public string Name { get; set; }
public int Age { get; set; }
public Form1()
{
InitializeComponent();
}
private async void button1_Click(object sender, EventArgs e)
{
// 使用属性存储数据
Name = "青青草原我最狂";
Age = 25;
// 调用带有耗时操作的异步方法
await DisplayInfoWithDelayAsync();
// 弹出消息框显示属性值
MessageBox.Show($"姓名:{Name}\n年龄:{Age}\n舍我其谁懒大王!");
}
// 带有耗时操作的异步方法
private async Task DisplayInfoWithDelayAsync()
{
Console.WriteLine("开始执行耗时操作...");
// 模拟从数据库中读取数据,等待2秒钟
await Task.Delay(2000);
// 在异步方法中使用属性
Console.WriteLine($"在 DisplayInfoWithDelayAsync 方法中:姓名:{Name},年龄:{Age}");
Console.WriteLine("耗时操作完成。");
}
}
}
在这个修改后的代码中,我添加了一段输出,用于在控制台中显示耗时操作的开始和结束。当你点击按钮时,可以在输出中看到开始和结束的标志,这段时间模拟了耗时操作的执行时间。在实际应用中,你可以将这里的 Task.Delay
替换为你真实的耗时操作。
提示
以上代码在VS2010中不可用,在VS2019及以上中可用
VS2010
VS2019
开启调试后,我们点击按钮
两秒钟后,跳出提示
总结
又是仓促的一天,现在上传的这个版本有些瑕疵,明天我会补好,感谢各位的阅读,喜欢本文的话,点赞收藏关注支持一下博主吧!感谢厚爱!
回到顶部