C#学习 [类型系统] 基本类型介绍(10)

在变量中指定类型

  1. 声明变量但不初始化
int i;
MyClass m;
  1. 声明且初始化
int i=0;
MyClass m=new MyClass();
  1. 方法中参数与返回值指定类型
public int getValue(int i){
    return i;
}

内置变量

C# 提供了一组标准的内置类型,这些类型可供在任何 C# 程序中使用。

  1. 基本变量
    img
  2. 引用变量
    img

在上表中,左侧列中的每个 C# 类型关键字(dynamic 除外)都是相应 .NET 类型的别名。 它们是可互换的。 例如,以下声明声明了相同类型的变量:

int a = 123;
System.Int32 b = 123;

自定义类型

可以使用 struct、class、interface、enum 和 record 构造来创建自己的自定义类型。

public class MyClass
{
    public static void Hello()
    {
        Console.WriteLine("hello from MyClass");
    }
}

通用类型系统

img

  • 类是引用类型。
  • 结构是值类型。
  • 记录类型可以是引用类型 (record class) 或值类型 (record struct)。

值类型

值类型派生自System.ValueType(派生自 System.Object)。 派生自 System.ValueType 的类型在 CLR 中具有特殊行为。 值类型变量直接包含其值。 结构的内存在声明变量的任何上下文中进行内联分配。 对于值类型变量,没有单独的堆分配或垃圾回收开销。 可以声明属于值类型的 record struct 类型,并包括记录的合成成员

值类型分为两类:struct和enum。

内置的数值类型是结构,它们具有可访问的字段和方法:

// constant field on type byte.
byte b = byte.MaxValue;
byte num = 0xA;
int i = 5;
char c = 'Z';
  1. struct
public struct Coords
{
    public Coords(double x, double y)
    {
        X = x;
        Y = y;
    }

    public double X { get; }
    public double Y { get; }

    public override string ToString() => $"({X}, {Y})";
}

可以使用 readonly 修饰符来声明结构类型为不可变。 readonly 结构的所有数据成员都必须是只读的,如下所示:
任何字段声明都必须具有 readonly 修饰符
任何属性(包括自动实现的属性)都必须是只读的,或者是 init 只读的。 请注意,仅限 init 的资源库从 C# 版本 9 开始可用。

public readonly struct Coords
{
    public Coords(double x, double y)
    {
        X = x;
        Y = y;
    }

    public double X { get; init; }
    public double Y { get; init; }

    public override string ToString() => $"({X}, {Y})";
}
public readonly double Sum()
{
    return X + Y;
}
public readonly override string ToString() => $"({X}, {Y})";
private int counter;
public int Counter
{
    readonly get => counter;
    set => counter = value;
}
public readonly double X { get; init; }
  1. enum

枚举定义的是一组已命名的整型常量。

public enum FileMode
{
    CreateNew = 1,
    Create = 2,
    Open = 3,
    OpenOrCreate = 4,
    Truncate = 5,
    Append = 6,
}

引用类型

定义为 class、record、delegate、数组或 interface 的类型是 reference type,引用类型完全支持继承。

在声明变量 reference type 时,它将包含值 null,直到你将其分配给该类型的实例,或者使用 new 运算符创建一个。

MyClass myClass = new MyClass();
MyClass myClass2 = myClass;
MyClass myClass = new MyClass();

// Declare and assign using an existing value.
IMyInterface myInterface = myClass;

// Or create and assign a value in a single statement.
IMyInterface myInterface2 = new MyClass();

创建对象时,会在托管堆上分配内存。 变量只保留对对象位置的引用。

所有数组都是引用类型,即使元素是值类型,也不例外

// Declare and initialize an array of integers.
int[] nums = { 1, 2, 3, 4, 5 };

// Access an instance property of System.Array.
int len = nums.Length;

文本值的类型

文本值从编译器接收类型。

string s = "The answer is " + 5.ToString();
// Outputs: "The answer is 5"
Console.WriteLine(s);

Type type = 12345.GetType();
// Outputs: "System.Int32"
Console.WriteLine(type);

泛型类型

可使用一个或多个类型参数声明的类型,用作实际类型(具体类型)的占位符 。

List<string> stringList = new List<string>();
stringList.Add("String example");
// 下面代码会造成编译错误:
stringList.Add(4);

通过使用类型参数,可重新使用相同类以保存任意类型的元素,且无需将每个元素转换为对象。

泛型集合类称为强类型集合。

隐式类型本地变量

可声明局部变量而无需提供显式类型。 var 关键字指示编译器通过初始化语句右侧的表达式推断变量的类型。

// i is compiled as an int
var i = 5;

// s is compiled as a string
var s = "Hello";

// a is compiled as int[]
var a = new[] { 0, 1, 2 };

// expr is compiled as IEnumerable<Customer>
// or perhaps IQueryable<Customer>
var expr =
    from c in customers
    where c.City == "London"
    select c;

// anon is compiled as an anonymous type
var anon = new { Name = "Terry", Age = 34 };

// list is compiled as List<int>
var list = new List<int>();

**带 var 关键字的隐式类型只能应用于本地方法范围内的变量。 隐式类型不可用于类字段。

指针类型(Pointer types)

指针类型变量存储另一种类型的内存地址。C# 中的指针与 C 或 C++ 中的指针有相同的功能。

char* cptr;
int* iptr;
posted @ 2024-10-30 10:04  huiy_小溪  阅读(27)  评论(0)    收藏  举报