C# 01代码笔记

本文详细介绍了.NETFramework中的ThreadStart与Thread类的区别,委托的使用、typeof关键字获取类型信息,C#属性的get和set访问器,以及null运算符、ref和out参数的用法,同时对比了Panel和TableLayoutPanel在WindowsForms中的作用。
摘要由CSDN通过智能技术生成
一、ThreadStart Thread 有啥区别

ThreadStartThread 是.NET Framework中用于多线程编程的两个关键类。

1.ThreadStart:

  • ThreadStart 是一个委托类型,通常用于表示在一个新的线程上执行的方法。
  • 它是一个代表不带参数并且没有返回值的方法的委托。当你希望在新线程上执行某个方法时,可以使用 ThreadStart 来引用该方法。

2.Thread:

  • Thread 类是表示操作系统线程的实体。它允许你创建和控制线程的执行。
  • 通过创建 Thread 对象,你可以为该对象指定一个委托(例如,ThreadStart 委托),这个委托将在新线程上执行。
二、如何理解委托

委托(Delegate)是一种类型,它允许你将方法作为参数传递、存储在变量中,并在稍后执行这些方法。委托提供了一种间接调用方法的机制,使得可以在运行时动态地选择和调用不同的方法。以下是对委托的一些关键概念和理解:

1.类型安全的函数指针: 委托可以被看作是类型安全的函数指针。它可以引用一个或多个方法,并且在调用时会检查方法的签名(参数类型和返回类型),以确保类型匹配。
2. 方法的封装: 委托允许你将一个或多个方法封装到一个委托实例中。这样,你可以将委托实例传递给其他代码,使其能够调用委托引用的方法,而无需知道具体的方法是什么。
3. 多播委托: 委托可以组合多个方法,形成一个多播委托。当调用多播委托时,它会按照添加顺序依次调用每个委托引用的方法。
4. 异步编程: 委托在异步编程中有着重要的应用。通过委托,你可以将一个方法作为异步操作的回调函数传递,使得在异步操作完成时能够自动调用指定的方法。
5. 事件: 事件是委托的一种特殊用法,用于实现发布-订阅模型。事件允许对象通知其他对象某个事件的发生,而其他对象可以订阅并在事件发生时执行特定的操作。

理解委托的关键是将其视为一种可用于间接调用方法的类型。它提供了一种松散耦合的方式,使得你可以更灵活地设计和组织代码,尤其在涉及回调、事件处理和异步操作时非常有用。

三、typeof

在 C# 中,typeof 是一个关键字,用于获取指定类型的 System.Type 对象。System.Type 类提供有关类型的信息,包括类的成员、方法、属性等。

使用 typeof 关键字的语法如下:

Type type = typeof(YourType);

其中,YourType 是你要获取信息的类型。例如:

Type stringType = typeof(string);
Type intType = typeof(int);

这样就可以获取 stringint 类型的 Type 对象。

通常,typeof 主要用于在运行时获取类型信息,以进行反射操作。例如,你可以使用 typeof 结合反射来动态创建实例、调用方法、获取属性等。

Type personType = typeof(Person);
object personInstance = Activator.CreateInstance(personType);
MethodInfo method = personType.GetMethod("SomeMethod");
method.Invoke(personInstance, null);

上述示例中,typeof(Person) 获取了 Person 类型的 Type 对象,然后通过反射创建了该类型的实例并调用了其中的方法。

总的来说,typeof 在 C# 中是一个用于获取类型信息的关键字,它是许多反射操作的基础。

四、C# 属性字段get set 访问器介绍
属性定义

属性的定义通常包含以下部分:

private int _myField; // 私有字段

public int MyProperty
{
    get
    {
        // get 访问器用于获取属性值
        return _myField;
    }
    set
    {
        // set 访问器用于设置属性值
        _myField = value;
    }
}

上述代码中,MyProperty 是一个属性,通过 getset 访问器提供对 _myField 字段的读写访问。

get 访问器

get 访问器用于获取属性的值。它包含在属性声明内部,并在访问属性时被自动调用。语法如下:

public int MyProperty
{
    get
    {
        // 返回属性值的逻辑
        return _myField;
    }
}
set 访问器

set 访问器用于设置属性的值。它也包含在属性声明内部,当给属性赋值时自动调用。语法如下:

public int MyProperty
{
    set
    {
        // 设置属性值的逻辑
        _myField = value;
    }
}
自动属性

在一些简单的情况下,C# 提供了自动属性,允许你在不显式定义字段的情况下声明属性。这样,编译器会自动创建一个私有字段并为你处理 getset 访问器的实现。例如:

public int MyProperty { get; set; }

这样的写法等效于:

private int _myField;

public int MyProperty
{
    get { return _myField; }
    set { _myField = value; }
}

总的来说,属性是一种在类中用于封装字段的机制,通过 getset 访问器可以控制对属性的读写访问。这提供了一种更灵活和安全的方式来访问和修改类的成员。

五、和null 相关的运算符
  1. ?. 运算符(null-conditional 运算符):
    • 该运算符允许你在访问可能为 null 的对象的成员时避免引发空引用异常(NullReferenceException)。
    • 如果操作符左侧的操作数为 null,则整个表达式的结果为 null,否则就会计算右侧的成员或方法调用。
    • 例如:object?.Propertyobject?.Method()
  2. ?? 运算符(null 合并运算符):

    • 该运算符用于在左侧操作数为 null 时提供一个备用值。如果左侧操作数为 null,则整个表达式的结果为右侧操作数,否则就使用左侧操作数的值。
    • 例如:nullableValue ?? defaultValuestringValue ?? "Default"

示例:

// 使用 ?. 运算符
string name = person?.Name;

// 使用 ?? 运算符
string displayName = name ?? "Unknown";

在上面的示例中,person?.Name 表示如果 person 不为 null,则获取其 Name 属性的值,否则 name 将为 null。接着,name ?? "Unknown" 表示如果 name 不为 null,则使用 name 的值,否则 displayName 将为字符串 “Unknown”。

  1. ?.[] 运算符(null-conditional 索引器运算符):
    • 类似于 ?. 运算符,但用于访问集合或数组的元素。
    • 例如:myArray?[index]myList?[0]
  2. ??= 运算符(null 合并赋值运算符):
    • 用于将右侧的值赋给左侧的变量,但只有当左侧变量为 null 时才执行赋值操作。
    • 例如:variable ??= expression
  3. is 模式匹配运算符:
    • 用于检查一个对象是否为某个特定类型,并在检查的同时进行类型转换。
    • 可以和 null 一起使用,例如:if (obj is MyClass myObj)
  4. ?.() 运算符(null-conditional 方法调用运算符):
    • 用于调用对象的方法,如果对象为 null,则整个表达式的结果为 null。
    • 例如:myObject?.MyMethod()
六、函数中的ref 和out
  1. ref 关键字:

    • ref 用于传递参数的引用。通过 ref 关键字,可以使得函数能够修改调用方传递的变量的值。

    • 使用 ref 关键字的参数必须在函数调用之前被初始化。

    • 示例:

      void ModifyValue(ref int x)
      {
          x = x * 2;
      }
      
      int num = 5;
      ModifyValue(ref num);
      // 现在,num 的值将变成 10
      
  2. out 关键字:

    • out 类似于 ref,也用于传递参数的引用。与 ref 不同的是,使用 out 的参数无需在函数调用之前被初始化。

    • 函数在使用 out 关键字时必须确保在函数结束之前为 out 参数赋值。

    • out 参数在函数内部必须赋值,否则会导致编译错误。

    • 示例:

      void InitializeValue(out int y)
      {
          y = 10;
      }
      
      int result;
      InitializeValue(out result);
      // 现在,result 的值将变成 10
      

总体来说,refout 关键字都用于在函数调用中传递参数引用,允许函数修改调用方的变量。ref 要求参数在调用前初始化,而 out 不要求。注意使用这两个关键字时应该小心,确保它们的使用场景和语义是合适的。

七、控件Panel

System.Windows.Forms.Panel 和System.Windows.Forms.TableLayoutPanel

  1. System.Windows.Forms.Panel

    • Panel 是一个容器控件,用于包含其他控件,并提供一个可视化的容器。它可以用作布局的容器,允许将其他控件放置在其内部。

    • Panel 通常用于将一组相关的控件组织在一起,并提供容器的外观和行为。你可以在 Panel 上放置按钮、文本框、标签等控件,以便更好地组织和管理用户界面。

    • 示例:

      csharpCopy code// 创建一个 Panel
      Panel myPanel = new Panel();
      // 将 Panel 添加到窗体上
      this.Controls.Add(myPanel);
      // 在 Panel 上添加其他控件
      Button myButton = new Button();
      myPanel.Controls.Add(myButton);
      
  2. System.Windows.Forms.TableLayoutPanel

    • TableLayoutPanel 是一个表格布局控件,用于以表格形式排列子控件。它提供了一种方便的方式来创建和管理复杂的布局,其中子控件可以根据行和列的定义来进行布局。

    • TableLayoutPanel 允许你以行和列的方式添加和排列控件,可以轻松实现灵活的布局,适用于需要在多个方向上对控件进行排列的情况。

    • 示例:

      // 创建一个 TableLayoutPanel
      TableLayoutPanel myTableLayoutPanel = new TableLayoutPanel();
      // 将 TableLayoutPanel 添加到窗体上
      this.Controls.Add(myTableLayoutPanel);
      // 在 TableLayoutPanel 上添加子控件,并指定行和列
      Button button1 = new Button();
      myTableLayoutPanel.Controls.Add(button1, 0, 0);  // 在第一行第一列
      Button button2 = new Button();
      myTableLayoutPanel.Controls.Add(button2, 1, 0);  // 在第一行第二列
      

这两个控件都是 Windows Forms 提供的布局和容器控件,用于帮助你更方便地创建和管理用户界面。选择使用哪一个取决于你的具体需求和布局结构。Panel 更自由形式,而 TableLayoutPanel 更适合需要表格式布局的情况。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值