C# - 数据类型

C# 数据类型简介

C# 数据类型定义变量可以存储的数据类型,例如整数、浮点数、字符或布尔值。数据类型对于声明用于存储相关值的特定变量、内存优化、性能提升和代码可读性至关重要。

在本章中,您将学习:

  • 不同的 C# 数据类型。
  • 使用特定数据类型声明和分配变量。
  • 关于编写高效代码的 C# 数据类型的最佳实践。
  • 声明和使用数据类型时应避免的常见错误。

C# 中的数据类型有哪些?

C# 数据类型指定变量可以存储的数据类型。在 C# 中,所有变量在使用前都必须声明其数据类型,因为它是一种强类型语言。

声明变量数据类型的语法

<data_type> <variable_name> = <value>;

C# 数据类型示例

using System;

class Program
{
    static void Main()
    {
        string studentName = "Sudhir Sharma";  
        int studentAge = 20;         
        double marksPercentage = 85.5;
        char grade = 'A';     
        bool isEnrolled = true; 

        Console.WriteLine("Student Name: " + studentName);
        Console.WriteLine("Age: " + studentAge);
        Console.WriteLine("Marks Percentage: " + marksPercentage + "%");
        Console.WriteLine("Grade: " + grade);
        Console.WriteLine("Enrolled: " + isEnrolled);
    }
}

此示例将产生以下输出:

Student Name: Sudhir Sharma
Age: 20
Marks Percentage: 85.5%
Grade: A
Enrolled: True

C# 中的数据类型

C# 中的变量分为以下几种类型:

  • 值类型
  • 引用类型
  • 指针类型

1. C# 中的值类型

值类型变量可以直接赋值。它们派生自 System.ValueType 类。

值类型直接包含数据。例如 int、char 和 float,分别存储数字、字母和浮点数。当您声明 int 类型时,系统会分配内存来存储该值。

值类型存储实际值,包括:

  • 整数类型(int、byte、long 等)
  • 浮点类型(float、double、decimal)
  • 字符类型 (char)
  • 布尔类型 (bool)
  • 枚举 (enum)
  • 结构体 (struct)

整数数据类型

数据类型 大小 范围
byte1 字节0 到 255
sbyte1 字节-128 到 127
short2 字节-32,768 到 32,767
ushort2 字节0 到 65,535
int4 字节-2,147,483,648 到 2,147,483,647
uint4字节0 到 4,294,967,295
long8 字节-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
ulong8 字节0 到 18,446,744,073,709,551,615

示例

using System;

class Program
{
    static void Main()
    {
        int studentID = 1024;
        long salary = 5000000L;
        byte experienceYears = 10;

        Console.WriteLine("Student ID: " + studentID);
        Console.WriteLine("Employee Salary: " + salary);
        Console.WriteLine("Experience (Years): " + experienceYears);
    }
}

此示例将产生以下输出:

Student ID: 1024
Employee Salary: 5000000
Experience (Years): 10

浮点数据类型

数据类型 大小 精度
float4 字节6-7 位小数
double8 字节15-16 位小数
decimal16 字节28-29 位小数

示例

using System;

class Program
{
    static void Main()
    {
        float gpa = 3.85f;
        double distance = 384400.5;
        decimal accountBalance = 15249.75m;

        Console.WriteLine("Student GPA: " + gpa);
        Console.WriteLine("Distance to Moon (km): " + distance);
        Console.WriteLine("Bank Account Balance: $" + accountBalance);
    }
}

此示例将产生以下输出:

Student GPA: 3.85
Distance to Moon (km): 384400.5
Bank Account Balance: $15249.75

使用 floatdouble 进行常规计算。

使用 decimal 进行精确的财务计算。

字符型和布尔型数据类型

数据类型 大小 描述
char2 个字节存储单个字符
bool1 个字节存储 true 或 false

示例

using System;

class Program
{
    static void Main()
    {
        bool isGraduate = true;
        char section = 'B';

        Console.WriteLine("Graduated: " + isGraduate);
        Console.WriteLine("Class Section: " + section);
    }
}

此示例将产生以下输出:

Graduated: True
Class Section: B

枚举 (enum)

enum 是一种用于定义命名常量值的特殊数据类型。

示例

using System;

class Program
{
    enum JobLevel { Intern, Junior, Mid, Senior, Manager }

    static void Main()
    {
        JobLevel currentLevel = JobLevel.Mid;
        Console.WriteLine("Current Job Level: " + currentLevel);
    }
}

此示例将产生以下输出:

Current Job Level: Mid

结构体

结构体 是一种用于封装关联数据的值类型。

示例

using System;

struct Employee
{
    public int ID;
    public string Name;
    public double Salary;
}

class Program
{
    static void Main()
    {
        Employee emp;
        emp.ID = 101;
        emp.Name = "Zoya";
        emp.Salary = 60000.50;

        Console.WriteLine("Employee ID: " + emp.ID);
        Console.WriteLine("Employee Name: " + emp.Name);
        Console.WriteLine("Employee Salary: $" + emp.Salary);
    }
}

此示例将产生以下输出:

Employee ID: 101
Employee Name: Zoya
Employee Salary: $60000.5

2. C# 中的引用类型

引用类型不包含变量中存储的实际数据,而是包含对变量的引用。

换句话说,它们指向一个内存位置。使用多个变量时,引用类型可以指向一个内存位置。如果其中一个变量更改了该内存位置中的数据,另一个变量的值也会自动反映更改。内置引用类型的示例包括:objectdynamicstringarray

对象类型

对象类型是 C# 通用类型系统 (CTS) 中所有数据类型的最终基类。Object 是 System.Object 类的别名。对象类型可以被赋值为任何其他类型、值类型、引用类型、预定义或用户定义类型的值。但是,在赋值之前,需要进行类型转换。

当值类型转换为对象类型时,这被称为装箱;另一方面,当对象类型转换为值类型时,这被称为拆箱

object obj;
obj = 100; // 这就是装箱

示例

using System;

class Program
{
    static void Main()
    {
        object obj = 1001; // Student ID
        Console.WriteLine("Student ID: " + obj);

        obj = "Sudhir Sharma"; // Student Name
        Console.WriteLine("Student Name: " + obj);
    }
}

此示例将产生以下输出:

Student ID: 1001
Student Name: Sudhir Sharma

动态类型

您可以在动态数据类型变量中存储任何类型的值。这些类型变量的类型检查在运行时进行。

声明动态类型的语法为:-

dynamic <variable_name> = value;

示例

using System;

class Program
{
    static void Main()
    {
        dynamic value = 10;
        Console.WriteLine("Dynamic value: " + value);

        value = "Hello, World!";
        Console.WriteLine("Dynamic now contains: " + value);
    }
}

此示例将产生以下输出:

Dynamic value: 10
Dynamic now contains: Hello, World!

动态类型与对象类型类似,不同之处在于对象类型变量的类型检查在编译时进行,而动态类型变量的类型检查在运行时进行。

字符串类型

字符串类型允许您将任何字符串值赋给变量。字符串类型是 System.String 类的别名。它派生自对象类型。字符串类型的值可以使用两种形式的字符串字面量赋值:quoted 和 @quoted。

示例

using System;

class Program
{
    static void Main()
    {
        string firstName = "Sudhir";
        string lastName = "Sharma";
        string fullName = firstName + " " + lastName;

        Console.WriteLine("Full Name: " + fullName);
    }
}

此示例将产生以下输出:

Full Name: Sudhir Sharma

注意:使用 StringBuilder 可以高效地修改字符串。

@quoted 字符串字面量如下所示 -

@"Tutorials Point";

用户定义的引用类型包括:类、接口或委托。我们将在后面的章节中讨论这些类型。

数组类型

数组将多个相同类型的值存储在一个变量中。

示例

using System;

class Program
{
    static void Main()
    {
        string[] students = { "Zoya", "Yashna", "Olivia", "Naomi" };
        
        Console.WriteLine("Student List:");
        foreach (string student in students)
        {
            Console.WriteLine(student);
        }
    }
}

此示例将产生以下输出:

Student List:
Zoya
Yashna
Olivia
Naomi

3. C# 中的指针类型

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

声明指针类型的语法为:-

type* identifier;

示例

using System;

unsafe class Program
{
    static void Main()
    {
        int grade = 90;
        int* ptr = &grade;

        Console.WriteLine("Original Grade: " + grade);
        Console.WriteLine("Memory Address: " + (ulong)ptr);

        *ptr = 95; // Modifying value using pointer
        Console.WriteLine("Updated Grade: " + grade);
    }
}

此示例将产生以下输出:

main.cs(3,1): error CS0227: Unsafe code requires the `unsafe' command line option to be specified
Compilation failed: 1 error(s), 0 warnings

C# 中的类型转换

在某些情况下,您可能需要更改变量的类型。类型转换允许您将数据从一种类型转换为另一种类型。在 C# 中,有两种类型转换:隐式显式

1. 隐式转换(安全)

当不存在数据丢失风险时,隐式转换会自动发生。C# 允许对兼容类型进行隐式转换。

示例

using System;

class Program
{
    static void Main()
    {
        int studentAge = 18;
        double preciseAge = studentAge;  // 隐式转换

        Console.WriteLine("Student Age (Integer): " + studentAge);
        Console.WriteLine("Converted to Double: " + preciseAge);
    }
}

此示例将产生以下输出:

Student Age (Integer): 18
Converted to Double: 18

2. 显式转换(强制类型转换)

在不兼容的类型之间进行转换时,需要进行显式转换。这可以通过强制类型转换来实现。

示例

using System;

class Program
{
    static void Main()
    {
        double salary = 50000.75;
        int roundedSalary = (int)salary; // 显式转换

        Console.WriteLine("Original Salary (Double): " + salary);
        Console.WriteLine("Rounded Salary (Integer): " + roundedSalary);
    }
}

此示例将产生以下输出:

Original Salary (Double): 50000.75
Rounded Salary (Integer): 50000

C# 中使用数据类型的最佳实践

  • 选择正确的数据类型:使用正确的数据类型有助于节省内存并提高程序效率。
  • 当类型显而易见时,使用 var:它可以提高可读性并使代码更简洁。
  • 避免不必要的类型转换:过于频繁地转换数据类型会降低性能。
  • 对固定值使用 constreadonly:这有助于防止意外更改重要值。
  • 使用 decimal 进行与金钱相关的计算:它可以提高财务计算的准确性交易。

常见错误及避免

1. 使用错误的数据类型

// 错误:应使用 `decimal`
float price = 100.99f;

修复:使用 decimal 进行与金钱相关的计算。

decimal price = 100.99m;

2.未处理引用类型中的空值

// 这将引发 NullReferenceException
string name;
Console.WriteLine(name.Length);

修复: 在使用字符串之前务必对其进行初始化。

string name = "sudhir";
Console.WriteLine(name.Length);

3. 赋值时忽略类型兼容性

// 编译错误:无法将字符串赋值给 int
int age = "25";

修复: 在将字符串赋值给整数之前,请正确转换字符串。

int age = int.Parse("25"); // 或 Convert.ToInt32("25")

C# 数据类型常见问题解答

问题 1:float、double 和 decimal 有什么区别?

  • float 用于近似计算。
  • double 提供更高的精度。
  • decimal 最适合用于财务数据。

问题 2:我可以将整数存储在 char 变量中吗?

不可以,但可以将整数转换为 char 类型:

char c = (char)65; // 输出 'A'

问题 3:存储大数的最佳方式是什么?

对于大整数,请使用 long 类型;对于大浮点值,请使用 double 类型。