C#完整教程

目录

第一部分:C# 基础

控制流

第二部分:面向对象编程(OOP)

第三部分:高级特性

第四部分:文件与 I/O 操作

第五部分:数据库操作

第六部分:图形用户界面(GUI)

第七部分:Web 开发

第八部分:游戏开发

第九部分:测试与调试

第十部分:部署与发布


第一部分:C# 基础

  1. C# 简介

    • C# 的历史与特点
    • .NET 框架与 .NET Core/.NET 5+ 的关系
    • 开发环境:Visual Studio、Visual Studio Code、Rider
  2. 第一个 C# 程序

    • Hello World 程序
    • 程序结构:命名空间、类、方法
    • 编译与运行
  3. 变量与数据类型

    • 基本数据类型:intfloatdoubleboolcharstring
    • 变量声明与初始化
    • 常量:const
    • 类型转换:隐式转换与显式转换
  4. 运算符

    • 算术运算符:+-*/%
    • 比较运算符:==!=><>=<=
    • 逻辑运算符:&&||!
    • 赋值运算符:=+=-=*=/=
    • 三元运算符:? :
      • 数组与字符串
        • 数组:声明、初始化、访问、遍历
        • 多维数组与锯齿数组
        • 字符串操作:stringStringBuilder
      句:breakcontinuereturn

运算符

算数运算符

1. 加法运算符(+

加法运算符用于将两个数值相加,也能用于拼接字符串。

using System;

class Program
{
    static void Main()
    {
        int num1 = 5;
        int num2 = 3;
        int sum = num1 + num2;
        Console.WriteLine($"两数相加的结果: {sum}");

        string str1 = "Hello";
        string str2 = " World";
        string combinedStr = str1 + str2;
        Console.WriteLine($"字符串拼接结果: {combinedStr}");
    }
}
2. 减法运算符(-

减法运算符用于从一个数值中减去另一个数值。

using System;

class Program
{
    static void Main()
    {
        int num1 = 5;
        int num2 = 3;
        int difference = num1 - num2;
        Console.WriteLine($"两数相减的结果: {difference}");
    }
}
3. 乘法运算符(*

乘法运算符用于将两个数值相乘。

using System;

class Program
{
    static void Main()
    {
        int num1 = 5;
        int num2 = 3;
        int product = num1 * num2;
        Console.WriteLine($"两数相乘的结果: {product}");
    }
}
4. 除法运算符(/

除法运算符用于将一个数值除以另一个数值。当操作数为整数时,结果会截断小数部分;若有一个操作数为浮点数,结果则为浮点数。

using System;

class Program
{
    static void Main()
    {
        int intNum1 = 10;
        int intNum2 = 3;
        int intQuotient = intNum1 / intNum2;
        Console.WriteLine($"整数相除的结果: {intQuotient}");

        double doubleNum1 = 10.0;
        double doubleNum2 = 3.0;
        double doubleQuotient = doubleNum1 / doubleNum2;
        Console.WriteLine($"浮点数相除的结果: {doubleQuotient}");
    }
}
5. 取模运算符(%

取模运算符用于计算两个数值相除后的余数。

using System;

class Program
{
    static void Main()
    {
        int num1 = 10;
        int num2 = 3;
        int remainder = num1 % num2;
        Console.WriteLine($"两数取模的结果: {remainder}");
    }
}
6. 自增运算符(++

自增运算符用于将变量的值加 1。可分为前缀自增(++variable)和后缀自增(variable++)。前缀自增会先将变量的值加 1,再返回变量的值;后缀自增则先返回变量的值,再将变量的值加 1。

using System;

class Program
{
    static void Main()
    {
        int num = 5;
        int prefixIncrement = ++num;
        Console.WriteLine($"前缀自增后的结果: {prefixIncrement}");

        num = 5;
        int postfixIncrement = num++;
        Console.WriteLine($"后缀自增后的结果: {postfixIncrement}");
        Console.WriteLine($"后缀自增后变量的值: {num}");
    }
}
7. 自减运算符(--

自减运算符用于将变量的值减 1。同样分为前缀自减(--variable)和后缀自减(variable--)。前缀自减先将变量的值减 1,再返回变量的值;后缀自减先返回变量的值,再将变量的值减 1。

using System;

class Program
{
    static void Main()
    {
        int num = 5;
        int prefixDecrement = --num;
        Console.WriteLine($"前缀自减后的结果: {prefixDecrement}");

        num = 5;
        int postfixDecrement = num--;
        Console.WriteLine($"后缀自减后的结果: {postfixDecrement}");
        Console.WriteLine($"后缀自减后变量的值: {num}");
    }
}

布尔逻辑运算符

在 C# 里,布尔逻辑运算符用于对布尔类型的值进行操作,其运算结果同样是布尔类型(true 或者 false)。下面为你详细介绍 C# 中常见的布尔逻辑运算符,同时给出相应的代码示例。

1. 逻辑与运算符(&&

当两个操作数都为 true 时,逻辑与运算符的运算结果才为 true;只要有一个操作数为 false,结果就为 false。它采用短路求值的方式,也就是说,若第一个操作数为 false,则不会再计算第二个操作数。

using System;

class Program
{
    static void Main()
    {
        bool condition1 = true;
        bool condition2 = false;

        bool result = condition1 && condition2;
        Console.WriteLine($"逻辑与运算结果: {result}");
    }
}
2. 逻辑或运算符(||

只要两个操作数中有一个为 true,逻辑或运算符的运算结果就为 true;只有当两个操作数都为 false 时,结果才为 false。它也采用短路求值的方式,若第一个操作数为 true,则不会再计算第二个操作数。

using System;

class Program
{
    static void Main()
    {
        bool condition1 = true;
        bool condition2 = false;

        bool result = condition1 || condition2;
        Console.WriteLine($"逻辑或运算结果: {result}");
    }
}
3. 逻辑非运算符(!

逻辑非运算符是一元运算符,它会对操作数的布尔值取反。若操作数为 true,则结果为 false;若操作数为 false,则结果为 true

using System;

class Program
{
    static void Main()
    {
        bool condition = true;

        bool result = !condition;
        Console.WriteLine($"逻辑非运算结果: {result}");
    }
}
4. 逻辑异或运算符(^

当两个操作数的布尔值不同时,逻辑异或运算符的运算结果为 true;若两个操作数的布尔值相同,则结果为 false

using System;

class Program
{
    static void Main()
    {
        bool condition1 = true;
        bool condition2 = false;

        bool result = condition1 ^ condition2;
        Console.WriteLine($"逻辑异或运算结果: {result}");
    }
}
5. 按位逻辑与运算符(&)和按位逻辑或运算符(|

& 和 | 既可以用作按位运算符处理整数类型,也能当作逻辑运算符处理布尔类型。与 && 和 || 不同的是,它们不会进行短路求值,也就是说,无论第一个操作数的结果如何,都会对第二个操作数进行计算。

using System;

class Program
{
    static void Main()
    {
        bool condition1 = true;
        bool condition2 = false;

        bool andResult = condition1 & condition2;
        bool orResult = condition1 | condition2;

        Console.WriteLine($"按位逻辑与运算结果: {andResult}");
        Console.WriteLine($"按位逻辑或运算结果: {orResult}");
    }
}

位运算符

        在 C# 中,位运算符用于对整数类型的操作数按二进制位进行操作。下面为你详细介绍常见的位运算符及其用法,并给出相应的代码示例。

1. 按位与运算符(&

        按位与运算符会对两个操作数的对应二进制位进行与运算。只有当两个对应位都为 1 时,结果的该位才为 1,否则为 0。

using System;

class Program
{
    static void Main()
    {
        int num1 = 5; // 二进制: 0101
        int num2 = 3; // 二进制: 0011
        int result = num1 & num2; // 二进制: 0001,十进制: 1
        Console.WriteLine($"按位与结果: {result}");
    }
}
2. 按位或运算符(|

        按位或运算符会对两个操作数的对应二进制位进行或运算。只要两个对应位中有一个为 1,结果的该位就为 1,只有当两个对应位都为 0 时,结果的该位才为 0。

using System;

class Program
{
    static void Main()
    {
        int num1 = 5; // 二进制: 0101
        int num2 = 3; // 二进制: 0011
        int result = num1 | num2; // 二进制: 0111,十进制: 7
        Console.WriteLine($"按位或结果: {result}");
    }
}
3. 按位异或运算符(^

        按位异或运算符会对两个操作数的对应二进制位进行异或运算。当两个对应位不同时,结果的该位为 1,相同时为 0。

using System;

class Program
{
    static void Main()
    {
        int num1 = 5; // 二进制: 0101
        int num2 = 3; // 二进制: 0011
        int result = num1 ^ num2; // 二进制: 0110,十进制: 6
        Console.WriteLine($"按位异或结果: {result}");
    }
}
4. 按位取反运算符(~

        按位取反运算符是一元运算符,它会对操作数的每个二进制位进行取反操作,即 0 变为 1,1 变为 0。

using System;

class Program
{
    static void Main()
    {
        int num = 5; // 二进制: 0101
        int result = ~num; 
        // 二进制补码表示:先取反得到 1010,再考虑符号位等,最终结果为 -6
        Console.WriteLine($"按位取反结果: {result}");
    }
}
5. 左移运算符(<<

        左移运算符会将操作数的二进制位向左移动指定的位数,右边空出的位用 0 填充。左移 n 位相当于将该数乘以 2 的 n 次方。

using System;

class Program
{
    static void Main()
    {
        int num = 5; // 二进制: 0101
        int result = num << 2; // 二进制: 010100,十进制: 20
        Console.WriteLine($"左移 2 位结果: {result}");
    }
}
6. 右移运算符(>>

        右移运算符会将操作数的二进制位向右移动指定的位数。对于无符号数,左边空出的位用 0 填充;对于有符号数,左边空出的位用符号位填充(正数补 0,负数补 1)。右移 n 位相当于将该数除以 2 的 n 次方(向下取整)。

using System;

class Program
{
    static void Main()
    {
        int num = 20; // 二进制: 010100
        int result = num >> 2; // 二进制: 000101,十进制: 5
        Console.WriteLine($"右移 2 位结果: {result}");
    }
}

关系运算符 

using System;

class Program
{
    static void Main()
    {
        int a = 10;
        int b = 20;

        // 等于
        Console.WriteLine($"a == b: {a == b}"); // false

        // 不等于
        Console.WriteLine($"a != b: {a != b}"); // true

        // 大于
        Console.WriteLine($"a > b: {a > b}"); // false

        // 小于
        Console.WriteLine($"a < b: {a < b}"); // true

        // 大于等于
        Console.WriteLine($"a >= b: {a >= b}"); // false

        // 小于等于
        Console.WriteLine($"a <= b: {a <= b}"); // true
    }
}

c#运算符优先级

using System;

class Program
{
    static void Main()
    {
        int a = 5;
        int b = 3;
        int c = 2;

        // 先计算乘法,再计算加法
        int result1 = a + b * c; 
        Console.WriteLine($"a + b * c 的结果: {result1}");

        // 先计算括号内的加法,再计算乘法
        int result2 = (a + b) * c; 
        Console.WriteLine($"(a + b) * c 的结果: {result2}");

        // 逻辑与运算符优先级高于逻辑或运算符
        bool condition1 = true || false && false; 
        Console.WriteLine($"true || false && false 的结果: {condition1}");

        // 加括号改变运算顺序
        bool condition2 = (true || false) && false; 
        Console.WriteLine("(true || false) && false 的结果: {condition2}");
    }
}

三元运算符

控制流

        控制流是编程中用于控制程序执行顺序的机制,主要包括条件语句、循环语句和跳转语句。

条件语句

        条件语句用于根据条件决定是否执行某段代码。

1.1 if 语句
int age = 18;
if (age >= 18)
{
    Console.WriteLine("You are an adult.");
}
1.2 if-else 语句
int age = 16;
if (age >= 18)
{
    Console.WriteLine("You are an adult.");
}
else
{
    Console.WriteLine("You are a minor.");
}
1.3 if-else if-else 语句
int score = 85;
if (score >= 90)
{
    Console.WriteLine("Grade: A");
}
else if (score >= 80)
{
    Console.WriteLine("Grade: B");
}
else if (score >= 70)
{
    Console.WriteLine("Grade: C");
}
else
{
    Console.WriteLine("Grade: D");
}
1.4 switch 语句

在 C# 里,switch 语句的控制表达式(也就是 switch 后面括号中的变量)所支持的数据类型如下:

整数类型

包含 sbytebyteshortushortintuintlongulong 以及 char 类型。这些类型的值可以直接用在 switch 语句中。

using System;

class Program
{
    static void Main()
    {
        int number = 2;
        switch (number)
        {
            case 1:
                Console.WriteLine("The number is 1.");
                break;
            case 2:
                Console.WriteLine("The number is 2.");
                break;
            default:
                Console.WriteLine("The number is neither 1 nor 2.");
                break;
        }
    }
}

枚举类型

自定义的枚举类型也能在 switch 语句里使用。

using System;

// 定义一个枚举类型
enum Weekday
{
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
}

class Program
{
    static void Main()
    {
        Weekday today = Weekday.Monday;
        switch (today)
        {
            case Weekday.Monday:
                Console.WriteLine("It's Monday.");
                break;
            case Weekday.Tuesday:
                Console.WriteLine("It's Tuesday.");
                break;
            // 其他情况可依次添加
            default:
                Console.WriteLine("It's another day.");
                break;
        }
    }
}

字符串类型

从 C# 7.0 起,switch 语句支持字符串类型。

using System;

class Program
{
    static void Main()
    {
        string color = "Red";
        switch (color)
        {
            case "Red":
                Console.WriteLine("The color is red.");
                break;
            case "Blue":
                Console.WriteLine("The color is blue.");
                break;
            default:
                Console.WriteLine("The color is neither red nor blue.");
                break;
        }
    }
}

可为空值类型

如果上述支持的类型是可为空值类型(例如 int?string? 等),同样可以在 switch 语句中使用。

using System;

class Program
{
    static void Main()
    {
        int? nullableNumber = 2;
        switch (nullableNumber)
        {
            case 1:
                Console.WriteLine("The number is 1.");
                break;
            case 2:
                Console.WriteLine("The number is 2.");
                break;
            case null:
                Console.WriteLine("The number is null.");
                break;
            default:
                Console.WriteLine("The number is neither 1 nor 2.");
                break;
        }
    }
}

模式匹配(C# 7.0 及更高版本)

从 C# 7.0 开始,switch 语句支持模式匹配,能对更多类型和条件进行匹配。

using System;

class Program
{
    static void Main()
    {
        object obj = 2;
        switch (obj)
        {
            case int i when i < 5:
                Console.WriteLine($"The integer is less than 5: {i}");
                break;
            case string s:
                Console.WriteLine($"The string is: {s}");
                break;
            default:
                Console.WriteLine("The object is of another type.");
                break;
        }
    }
}

不支持的类型 

浮点类型

float 和 double 类型不适合用于 switch 语句,这是因为浮点数在计算机中是以二进制近似表示的,存在精度问题。例如,两个理论上相等的浮点数在计算机中可能由于精度误差而不相等,这样就无法准确匹配 case 标签。

using System;

class Program
{
    static void Main()
    {
        double num = 0.1 + 0.2;
        // 由于精度问题,这里的比较可能不会按预期工作
        switch (num)
        {
            case 0.3:
                Console.WriteLine("The number is 0.3");
                break;
            default:
                Console.WriteLine("The number is not 0.3");
                break;
        }
    }
}

在这个例子中,尽管数学上 0.1 + 0.2 等于 0.3,但由于浮点数精度问题,switch 语句可能不会匹配到 case 0.3

引用类型(除字符串)

一般的引用类型(如自定义类、数组等)不支持直接用于 switch 语句,因为引用类型比较的是引用地址而非值本身。不过,字符串类型是个例外,从 C# 7.0 开始支持在 switch 语句中使用。

using System;

class MyClass
{
    public int Value { get; set; }
}

class Program
{
    static void Main()
    {
        MyClass obj1 = new MyClass { Value = 1 };
        MyClass obj2 = new MyClass { Value = 1 };
        // 以下代码会报错,因为 MyClass 类型不能直接用于 switch 语句
        // switch (obj1)
        // {
        //     case obj2:
        //         Console.WriteLine("Objects are equal");
        //         break;
        //     default:
        //         Console.WriteLine("Objects are not equal");
        //         break;
        // }
    }
}

布尔类型以外的逻辑类型

除了布尔类型,像 bool?(可为空的布尔类型)可以在 switch 中使用外,其他逻辑相关的自定义类型如果没有合适的转换机制,也不能直接用于 switch 语句。

动态类型

dynamic 类型也不能直接用于 switch 语句,因为在编译时无法确定 dynamic 类型的具体值,switch 语句需要在编译时确定可能的 case 标签。

using System;

class Program
{
    static void Main()
    {
        dynamic value = 1;
        // 以下代码会报错,因为 dynamic 类型不能用于 switch 语句
        // switch (value)
        // {
        //     case 1:
        //         Console.WriteLine("Value is 1");
        //         break;
        //     default:
        //         Console.WriteLine("Value is not 1");
        //         break;
        // }
    }
}

示例 1:简单的 switch 语句

int day = 3;
switch (day)
{
    case 1:
        Console.WriteLine("Monday");
        break;
    case 2:
        Console.WriteLine("Tuesday");
        break;
    case 3:
        Console.WriteLine("Wednesday");
        break;
    default:
        Console.WriteLine("Invalid day");
        break;
}

输出:

Wednesday

示例 2:多个 case 共享代码块

int month = 2;
switch (month)
{
    case 1:
    case 3:
    case 5:
    case 7:
    case 8:
    case 10:
    case 12:
        Console.WriteLine("31 days");
        break;
    case 4:
    case 6:
    case 9:
    case 11:
        Console.WriteLine("30 days");
        break;
    case 2:
        Console.WriteLine("28 or 29 days");
        break;
    default:
        Console.WriteLine("Invalid month");
        break;
}

输出:

28 or 29 days

示例 3:switch 与字符串

string fruit = "Apple";
switch (fruit)
{
    case "Apple":
        Console.WriteLine("It's an apple.");
        break;
    case "Banana":
        Console.WriteLine("It's a banana.");
        break;
    default:
        Console.WriteLine("Unknown fruit.");
        break;
}

输出:

It's an apple.

switch 语句与模式匹配

using System;
 
class Program
{
    static void Main(string[] args)
    {
        int score;
        Console.Write("请输入学生的分数:");
        score = Convert.ToInt32(Console.ReadLine());
 
        string grade;
        switch (score)
        {
            case int n when (n >= 90 && n <= 100):
                grade = "优秀";
                break;
            case int n when (n >= 80 && n < 90):
                grade = "良好";
                break;
            case int n when (n >= 70 && n < 80):
                grade = "中等";
                break;
            case int n when (n >= 60 && n < 70):
                grade = "及格";
                break;
            default:
                grade = "不及格";
                break;
        }
 
        Console.WriteLine("学生的成绩分类为:" + grade);
    }
}

switch 表达式(C#8.0及以上)

using System;

class Program
{
    static void Main(string[] args)
    {
        int score;
        while (true)
        {
            Console.Write("请输入学生的分数:");
            if (int.TryParse(Console.ReadLine(), out score) && score >= 0 && score <= 100)
            {
                break;
            }
            Console.WriteLine("输入无效,请输入 0 到 100 之间的整数。");
        }

        string grade = score switch
        {
            >= 90 and <= 100 => "优秀",
            >= 80 and < 90 => "良好",
            >= 70 and < 80 => "中等",
            >= 60 and < 70 => "及格",
            _ => "不及格"
        };

        Console.WriteLine("学生的成绩分类为:" + grade);
    }
}

循环语句

        循环语句用于重复执行某段代码,直到满足特定条件。

2.1 for 循环
for (int i = 0; i < 5; i++)
{
    Console.WriteLine("Iteration: " + i);
}
2.2 while 循环
int i = 0;
while (i < 5)
{
    Console.WriteLine("Iteration: " + i);
    i++;
}
2.3 do-while 循环
int i = 0;
do
{
    Console.WriteLine("Iteration: " + i);
    i++;
} while (i < 5);
2.4 foreach 循环
string[] fruits = { "Apple", "Banana", "Cherry" };
foreach (string fruit in fruits)
{
    Console.WriteLine(fruit);
}

跳转语句

        跳转语句用于改变程序的执行顺序。

3.1 break 语句
  • 用于退出循环或 switch 语句。
for (int i = 0; i < 10; i++)
{
    if (i == 5)
    {
        break; // 退出循环
    }
    Console.WriteLine("Iteration: " + i);
}
3.2 continue 语句
  • 用于跳过当前循环的剩余部分,直接进入下一次循环。
for (int i = 0; i < 10; i++)
{
    if (i % 2 == 0)
    {
        continue; // 跳过偶数
    }
    Console.WriteLine("Iteration: " + i);
}
3.3 return 语句
  • 用于从方法中返回值并退出方法。
int Add(int a, int b)
{
    return a + b;
}
int result = Add(3, 5); // result = 8
3.4 goto 语句
  • 用于跳转到指定的标签(不推荐使用,容易导致代码混乱)。
int i = 0;
start:
if (i < 5)
{
    Console.WriteLine("Iteration: " + i);
    i++;
    goto start; // 跳转到 start 标签
}

第二部分:面向对象编程(OOP)

类与对象

通过程序观察初步认识面向对象编程

using System;

// 定义一个简单的类
class Person
{
    // 字段
    private string name;
    private int age;

    // 构造函数
    public Person(string name, int age)
    {
        this.name = name;
        this.age = age;
    }

    // 方法
    public void Introduce()
    {
        Console.WriteLine($"我叫 {name},今年 {age} 岁。");
    }
}

class Program
{
    static void Main()
    {
        // 创建对象
        Person person = new Person("张三", 25);
        // 调用对象的方法
        person.Introduce();
    }
}

类与对象的产生使用和组成规范 

  1. 方法

    • 方法的定义与调用
    • 参数传递:值传递与引用传递(refout
    • 方法重载
  2. 访问修饰符

    • publicprivateprotectedinternal
    • 封装的概念
  3. 继承

    • 基类与派生类
    • base 关键字
    • 方法重写:overridevirtual
  4. 多态

    • 抽象类与抽象方法:abstract
    • 接口:interface
    • 接口与抽象类的区别
  5. 静态成员

    • 静态字段与静态方法
    • 静态类
    • static 关键字的使用场景

C#完整教程资源描述 C#(发音为“C Sharp”)是一种面向对象的编程语言,由微软公司开发,并已成为.NET框架的核心语言之一。学习C#不仅可以帮助你掌握强大的编程技能,还能让你深入了解.NET生态系统。以下是一份关于C#完整教程的资源描述,旨在为初学者和有一定基础的学习者提供全面的指导。 一、教程目标 本教程的目标是帮助读者从零开始学习C#编程语言,逐步掌握其语法、特性以及实际应用。无论是初学者还是有一定编程基础但希望深入了解C#的学习者,都能通过本教程获得系统的知识体系。通过学习,读者将能够编写出结构清晰、功能强大的C#程序,并具备解决实际问题的能力。 二、教程内容 (一)基础语法 C#简介 介绍C#的历史背景、设计目标以及与其他编程语言的比较。 讲解C#在.NET框架中的地位和作用。 开发环境搭建 详细介绍如何安装Visual Studio或Visual Studio Code等开发工具。 配置开发环境,包括创建第一个C#项目的基本步骤。 基本语法 数据类型:讲解C#中的值类型(如int、float、bool等)和引用类型(如string、数组等)。 变量与常量:如何声明和使用变量,以及常量的定义和作用。 运算符:包括算术运算符、关系运算符、逻辑运算符等的使用方法。 控制结构:if-else语句、switch语句、循环语句(for、while、do-while)的语法和应用场景。 (二)面向对象编程 类与对象 介绍类的概念,如何定义类以及类的成员(属性、方法、构造函数等)。 对象的创建和使用,以及如何通过对象调用类的成员。 继承与多态 讲解继承的基本概念,如何实现类的继承以及继承的规则。 多态的两种表现形式:方法重载和方法覆盖,通过实例展示多态的强大功能。 接口与抽象类 接口的定义和实现,以及接口在编程中的重要性。 抽象类的概念,如何定义抽象类和抽象方法,以及抽象
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值