目 录CONTENT

文章目录

CSharp(十八) 方法(Method)详解

CSharp(十八) 方法(Method)详解

目录

  1. 方法的基本概念
  2. 方法的定义
  3. 方法的参数
  4. 方法的返回值
  5. 方法重载
  6. 具体使用示例

1. 方法的基本概念

方法(Method) 是一段可重用的代码块,用于执行特定的操作或计算。方法是 C# 中最基本的代码组织单元,属于类(class)或结构体(struct)的成员。

方法的核心作用:

  • 代码复用:避免重复编写相同逻辑
  • 模块化:将复杂问题拆解为多个小方法
  • 封装:隐藏实现细节,对外暴露统一接口
  • 可维护性:修改一处,处处生效

2. 方法的定义

2.1 基本语法

// [访问修饰符] [其他修饰符] 返回类型 方法名([参数列表])
// {
//     // 方法体
//     [return 返回值;]
// }

2.2 完整组成要素

要素 说明 是否必须
访问修饰符 public / private / protected / internal / protected internal / private protected 可选(默认 private)
其他修饰符 static / abstract / virtual / override / sealed / async / partial / extern 可选
返回类型 任意数据类型、void、Task 等 必须
方法名 符合 C# 命名规范(PascalCase) 必须
参数列表 圆括号包围的逗号分隔参数 必须(无参时为空括号)
方法体 花括号包围的代码块 必须(抽象方法和分部方法除外)

2.3 基本示例

public class Calculator
{
    // 无参数、无返回值的方法
    public void SayHello()
    {
        Console.WriteLine("Hello, C#!");
    }

    // 有参数、有返回值的方法
    public int Add(int a, int b)
    {
        return a + b;
    }

    // 静态方法(属于类本身,不依赖实例)
    public static double PI()
    {
        return 3.141592653589793;
    }
}

2.4 表达式体方法(C# 6.0 / 7.0+)

对于只有一条语句的简单方法,可以使用表达式体语法:

// 表达式体方法(无返回值)
public void Print(string msg) => Console.WriteLine(msg);

// 表达式体方法(有返回值)
public int Multiply(int a, int b) => a * b;

// 静态表达式体方法
public static double Square(double x) => x * x;

3. 方法的参数

3.1 值参数(Value Parameter)— 默认方式

按值传递,方法内修改不影响原变量(对于引用类型则是复制引用地址)。

public void Increment(int num)
{
    num++;  // 不影响调用处的原变量
    Console.WriteLine($"方法内部: {num}");
}

// 调用
int value = 10;
Increment(value);          // 输出: 方法内部: 11
Console.WriteLine(value);  // 输出: 10(原值不变)

对于引用类型(如 class),复制的是引用,因此修改对象的属性会影响原对象:

public class Person
{
    public string Name { get; set; }
}

public void ChangeName(Person p)
{
    p.Name = "李四";  // 会修改原对象的属性
    p = new Person { Name = "王五" };  // 不会影响原引用
}

3.2 引用参数(ref Parameter)

使用 ref 关键字,传递的是变量的引用,方法内修改会影响原变量。

要求:变量在传入前必须先初始化。

public void Swap(ref int x, ref int y)
{
    int temp = x;
    x = y;
    y = temp;
}

// 调用
int a = 10, b = 20;
Swap(ref a, ref b);
Console.WriteLine($"a={a}, b={b}");  // 输出: a=20, b=10

3.3 输出参数(out Parameter)

使用 out 关键字,用于从方法返回多个值。

特点

  • 变量传入前可以不初始化
  • 方法内必须给 out 参数赋值
public bool TryParseInt(string input, out int result)
{
    // out 参数在方法返回前必须被赋值
    return int.TryParse(input, out result);
}

// 调用
if (TryParseInt("123", out int number))
{
    Console.WriteLine($"解析成功: {number}");  // 输出: 解析成功: 123
}

C# 7.0+ 内联声明:可以在调用时直接声明 out 变量。

// 内联声明 out 变量
TryParseInt("456", out int num);
Console.WriteLine(num);  // 456

3.4 参数数组(params Parameter)

使用 params 关键字,允许传递可变数量的实参。

限制

  • 必须是参数列表中的最后一个参数
  • 只能有一个 params 参数
  • 必须是一维数组类型
public int Sum(params int[] numbers)
{
    int total = 0;
    foreach (int n in numbers)
    {
        total += n;
    }
    return total;
}

// 调用方式
int result1 = Sum(1, 2, 3);                 // 6
int result2 = Sum(1, 2, 3, 4, 5, 6, 7);     // 28
int result3 = Sum(new int[] { 10, 20, 30 }); // 60(也可以传数组)
int result4 = Sum();                          // 0(可以不传参数)

3.5 可选参数(Optional Parameter)

为参数指定默认值,调用时可以省略该参数。

限制:可选参数必须出现在所有必需参数之后。

public string Greet(string name, string greeting = "你好", string punctuation = "!")
{
    return $"{greeting},{name}{punctuation}";
}

// 调用
Console.WriteLine(Greet("小明"));                      // 你好,小明!
Console.WriteLine(Greet("小明", "早上好"));             // 早上好,小明!
Console.WriteLine(Greet("小明", "Good morning", ".")); // Good morning,小明.

// 命名参数,可以跳过中间的可选参数
Console.WriteLine(Greet("小明", punctuation: "。"));   // 你好,小明。

3.6 命名参数(Named Parameter)

调用时通过参数名指定值,不依赖参数位置顺序。

public void CreateUser(string name, int age, string email, bool isActive = true)
{
    Console.WriteLine($"姓名:{name}, 年龄:{age}, 邮箱:{email}, 激活:{isActive}");
}

// 使用命名参数,可以不按顺序
CreateUser(age: 25, name: "张三", email: "zhangsan@example.com");
CreateUser("李四", email: "lisi@test.com", age: 30, isActive: false);

3.7 in 参数(只读引用参数,C# 7.2+)

使用 in 关键字,以引用方式传递但不可修改。适用于大型值类型的传递以提升性能。

public struct LargeStruct
{
    public int A, B, C, D, E, F, G, H;
}

// in 参数:按引用传递但不可修改
public int Sum(in LargeStruct data)
{
    // data.A = 10;  // 编译错误!不能修改 in 参数
    return data.A + data.B + data.C + data.D;
}

// 调用(in 在调用处可省略)
LargeStruct ls = new LargeStruct { A = 1, B = 2, C = 3, D = 4 };
int result = Sum(ls);       // in 可省略
int result2 = Sum(in ls);   // 或显式使用 in

3.8 各参数类型对比总结

参数类型 关键字 传入前初始化 方法内必须赋值 方法内修改影响外部
值参数(默认) 否(值类型)/ 部分(引用类型属性)
引用参数 ref
输出参数 out
参数数组 params
可选参数 默认值 否(可省略)
in 参数 in 否(只读)

4. 方法的返回值

4.1 void — 无返回值

方法执行操作但不返回任何数据。

public void Log(string message)
{
    Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {message}");
    // 可以省略 return 语句
    // 或者使用 return; (仅跳出方法)
}

4.2 返回基本类型

public int Add(int a, int b)
{
    return a + b;
}

public bool IsEven(int number)
{
    return number % 2 == 0;
}

public string GetFullName(string firstName, string lastName)
{
    return $"{lastName}{firstName}";
}

4.3 返回自定义类型 / 集合

public class Student
{
    public string Name { get; set; }
    public int Score { get; set; }
}

public Student FindTopStudent(List<Student> students)
{
    if (students == null || students.Count == 0)
        return null;  // 可以返回 null

    var top = students[0];
    foreach (var s in students)
    {
        if (s.Score > top.Score)
            top = s;
    }
    return top;
}

public List<Student> GetPassedStudents(List<Student> students, int passLine = 60)
{
    return students.Where(s => s.Score >= passLine).ToList();
}

4.4 返回多个值 — Tuple(元组)

C# 7.0+ 元组(推荐):

// 命名元组
public (int Min, int Max, double Average) Analyze(int[] numbers)
{
    if (numbers == null || numbers.Length == 0)
        throw new ArgumentException("数组不能为空");

    int min = numbers[0], max = numbers[0];
    double sum = 0;

    foreach (int n in numbers)
    {
        if (n < min) min = n;
        if (n > max) max = n;
        sum += n;
    }

    return (min, max, sum / numbers.Length);
}

// 调用与解构
int[] data = { 3, 1, 7, 5, 9, 2 };
var result = Analyze(data);
Console.WriteLine($"最小值:{result.Min}, 最大值:{result.Max}, 平均值:{result.Average:F2}");

// 直接解构
var (min, max, avg) = Analyze(data);
Console.WriteLine($"min={min}, max={max}, avg={avg:F2}");

System.Tuple(旧版)

public Tuple<int, int, double> AnalyzeOld(int[] numbers)
{
    // ... 计算逻辑
    return Tuple.Create(min, max, average);
}

// 调用
var result = AnalyzeOld(data);
Console.WriteLine($"Item1:{result.Item1}, Item2:{result.Item2}, Item3:{result.Item3}");

4.5 返回多个值 — out 参数

public bool Divide(int dividend, int divisor, out int quotient, out int remainder)
{
    if (divisor == 0)
    {
        quotient = 0;
        remainder = 0;
        return false;
    }
    quotient = dividend / divisor;
    remainder = dividend % divisor;
    return true;
}

// 调用
if (Divide(17, 5, out int q, out int r))
{
    Console.WriteLine($"商={q}, 余数={r}");  // 商=3, 余数=2
}

4.6 返回 IEnumerable — 迭代器方法(yield return)

public IEnumerable<int> GetFibonacci(int count)
{
    int a = 0, b = 1;
    for (int i = 0; i < count; i++)
    {
        yield return a;
        int temp = a + b;
        a = b;
        b = temp;
    }
}

// 调用(延迟执行)
foreach (int num in GetFibonacci(10))
{
    Console.Write($"{num} ");  // 0 1 1 2 3 5 8 13 21 34
}

4.7 返回 async Task — 异步方法

public async Task<string> DownloadContentAsync(string url)
{
    using var client = new HttpClient();
    string content = await client.GetStringAsync(url);
    return content;
}

// 无返回值的异步方法
public async Task ProcessDataAsync()
{
    await Task.Delay(1000);  // 模拟耗时操作
    Console.WriteLine("处理完成");
}

// 返回 Task<T>
public async Task<int> CalculateAsync()
{
    return await Task.Run(() =>
    {
        Thread.Sleep(500);
        return 42;
    });
}

4.8 提前返回与 guard clause

public decimal CalculateDiscount(User user, decimal amount)
{
    // Guard clauses — 提前返回异常情况
    if (user == null)
        throw new ArgumentNullException(nameof(user));
    if (amount <= 0)
        return 0;

    // 业务逻辑
    if (user.IsVIP)
        return amount * 0.2m;
    if (user.YearsOfMembership > 5)
        return amount * 0.1m;

    return 0;
}

5. 方法重载(Overloading)

5.1 重载的概念

方法重载 是指同一个类中可以定义多个名称相同参数列表不同(参数数量、类型或顺序不同)的方法。

规则

可以作为重载区分依据 不可以作为重载区分依据
参数数量不同 仅返回值类型不同
参数类型不同 仅参数名不同
参数类型顺序不同(建议避免) 仅修饰符不同(ref/out)
- params 与普通数组参数

5.2 基本重载示例

public class Formatter
{
    // 无参数
    public string Format()
    {
        return "默认格式化";
    }

    // 重载:参数数量不同
    public string Format(string text)
    {
        return $"【格式化】{text}";
    }

    // 重载:参数类型不同
    public string Format(int number)
    {
        return $"数字格式化: {number:N0}";
    }

    // 重载:参数类型不同
    public string Format(DateTime date)
    {
        return $"日期格式化: {date:yyyy年MM月dd日}";
    }

    // 重载:两个不同类型参数
    public string Format(string text, int repeat)
    {
        return string.Concat(Enumerable.Repeat(text, repeat));
    }

    // 重载:参数类型顺序不同(不推荐,容易产生歧义)
    public string Format(int repeat, string text)
    {
        return string.Concat(Enumerable.Repeat(text, repeat));
    }
}

5.3 构造函数重载

public class Rectangle
{
    public double Width { get; }
    public double Height { get; }

    // 默认构造函数
    public Rectangle() : this(1, 1)  // 调用下面的构造函数
    {
    }

    // 正方形构造函数
    public Rectangle(double side) : this(side, side)
    {
    }

    // 主构造函数
    public Rectangle(double width, double height)
    {
        Width = width;
        Height = height;
    }

    public double Area() => Width * Height;
}

// 使用
var r1 = new Rectangle();           // 1 x 1
var r2 = new Rectangle(5);          // 5 x 5
var r3 = new Rectangle(4, 6);       // 4 x 6

5.4 运算符重载

public readonly struct Complex : IEquatable<Complex>
{
    public double Real { get; }
    public double Imaginary { get; }

    public Complex(double real, double imaginary)
    {
        Real = real;
        Imaginary = imaginary;
    }

    // 重载 + 运算符
    public static Complex operator +(Complex a, Complex b)
        => new Complex(a.Real + b.Real, a.Imaginary + b.Imaginary);

    // 重载 - 运算符
    public static Complex operator -(Complex a, Complex b)
        => new Complex(a.Real - b.Real, a.Imaginary - b.Imaginary);

    // 重载 * 运算符
    public static Complex operator *(Complex a, Complex b)
        => new Complex(
            a.Real * b.Real - a.Imaginary * b.Imaginary,
            a.Real * b.Imaginary + a.Imaginary * b.Real);

    // 重载 == 和 != 运算符
    public static bool operator ==(Complex a, Complex b) => a.Equals(b);
    public static bool operator !=(Complex a, Complex b) => !a.Equals(b);

    // 隐式转换重载
    public static implicit operator Complex(double real) => new Complex(real, 0);

    // 重写 Equals 和 GetHashCode(与运算符重载配套)
    public override bool Equals(object obj) => obj is Complex c && Equals(c);
    public bool Equals(Complex other) => Real == other.Real && Imaginary == other.Imaginary;
    public override int GetHashCode() => HashCode.Combine(Real, Imaginary);
    public override string ToString() => $"({Real} + {Imaginary}i)";
}

// 使用
var c1 = new Complex(3, 4);
var c2 = new Complex(1, 2);
Complex c3 = c1 + c2;    // (4 + 6i)
Complex c4 = 5;           // 隐式转换 (5 + 0i)

5.5 泛型方法与重载

public class Repository
{
    // 泛型方法
    public T GetById<T>(int id) where T : class
    {
        Console.WriteLine($"获取 {typeof(T).Name},ID={id}");
        return default;  // 实际中会查询数据库
    }

    // 重载泛型方法(不同参数数量)
    public T GetById<T>(int id, bool includeDeleted) where T : class
    {
        Console.WriteLine($"获取 {typeof(T).Name},ID={id},包含已删除:{includeDeleted}");
        return default;
    }

    public string GetById(string entityName, int id)
    {
        return $"实体:{entityName}, ID:{id}";
    }
}

6. 具体使用示例

6.1 综合示例:学生管理系统

using System;
using System.Collections.Generic;
using System.Linq;

namespace StudentManagement
{
    // 学生实体类
    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
        public List<double> Scores { get; set; } = new List<double>();

        public override string ToString()
            => $"学号:{Id}, 姓名:{Name}, 年龄:{Age}";
    }

    // 学生管理服务
    public class StudentManager
    {
        private readonly List<Student> _students = new List<Student>();
        private int _nextId = 1;

        // ========== 添加学生(重载)==========

        // 重载1:最少信息
        public Student AddStudent(string name, int age)
        {
            return AddStudent(name, age, Array.Empty<double>());
        }

        // 重载2:包含成绩
        public Student AddStudent(string name, int age, params double[] scores)
        {
            var student = new Student
            {
                Id = _nextId++,
                Name = name,
                Age = age,
                Scores = scores.ToList()
            };
            _students.Add(student);
            return student;
        }

        // 重载3:通过已有 Student 对象添加
        public Student AddStudent(Student student)
        {
            if (student == null)
                throw new ArgumentNullException(nameof(student));
            student.Id = _nextId++;
            _students.Add(student);
            return student;
        }

        // ========== 查找学生 ==========

        // 返回单个值 + out 参数
        public bool TryFindStudent(int id, out Student found)
        {
            found = _students.FirstOrDefault(s => s.Id == id);
            return found != null;
        }

        // 使用 Tuple 返回多项统计
        public (Student TopStudent, double Average, int Count) GetStatistics()
        {
            if (_students.Count == 0)
                return (null, 0, 0);

            var allScores = _students.SelectMany(s => s.Scores).ToList();
            double avg = allScores.Count > 0 ? allScores.Average() : 0;

            Student top = _students
                .Where(s => s.Scores.Count > 0)
                .OrderByDescending(s => s.Scores.Max())
                .FirstOrDefault();

            return (top, avg, _students.Count);
        }

        // 使用 ref 参数修改数据
        public bool UpdateAge(int id, ref int newAge)
        {
            if (TryFindStudent(id, out var student))
            {
                student.Age = newAge;
                return true;
            }
            return false;
        }

        // params 批量删除
        public int RemoveStudents(params int[] ids)
        {
            return _students.RemoveAll(s => ids.Contains(s.Id));
        }

        // 可选参数 + 可空值类型
        public List<Student> Filter(
            int? minAge = null,
            int? maxAge = null,
            string nameContains = null,
            int limit = 10)
        {
            var query = _students.AsEnumerable();

            if (minAge.HasValue)
                query = query.Where(s => s.Age >= minAge.Value);

            if (maxAge.HasValue)
                query = query.Where(s => s.Age <= maxAge.Value);

            if (!string.IsNullOrEmpty(nameContains))
                query = query.Where(s => s.Name.Contains(nameContains));

            return query.Take(limit).ToList();
        }

        // 迭代器方法
        public IEnumerable<Student> GetAllStudents()
        {
            foreach (var student in _students)
            {
                yield return student;
            }
        }

        // 异步方法
        public async Task<List<Student>> FilterAsync(int? minAge = null)
        {
            await Task.Delay(10);  // 模拟异步操作
            return Filter(minAge: minAge);
        }
    }

    // ========== 使用示例 ==========
    class Program
    {
        static async Task Main(string[] args)
        {
            var manager = new StudentManager();

            // 使用不同的 AddStudent 重载
            manager.AddStudent("张三", 20);
            manager.AddStudent("李四", 22, 85, 92, 78, 95);
            manager.AddStudent("王五", 19, 90, 88, 76);
            manager.AddStudent("赵六", 21, 70, 65, 80);

            // 使用 TryFindStudent(含 out 参数)
            if (manager.TryFindStudent(2, out var student))
            {
                Console.WriteLine($"找到学生: {student}");
            }

            // 使用 Tuple 统计
            var (topStudent, average, totalCount) = manager.GetStatistics();
            Console.WriteLine($"第一名: {topStudent?.Name}, 平均分: {average:F2}, 总人数: {totalCount}");

            // 使用 ref 参数
            int newAge = 23;
            manager.UpdateAge(1, ref newAge);

            // 使用可选参数过滤
            var teens = manager.Filter(minAge: 13, maxAge: 20);
            Console.WriteLine($"\n青少年组({teens.Count}人):");
            foreach (var s in teens)
                Console.WriteLine($"  {s}");

            // 使用命名参数
            var namedFilter = manager.Filter(nameContains: "张", limit: 5);

            // 使用异步方法
            var allStudents = await manager.FilterAsync();

            // 使用 params 删除
            int removed = manager.RemoveStudents(3, 4);
            Console.WriteLine($"\n已删除 {removed} 名学生");
        }
    }
}

6.2 扩展方法(Extension Method)

扩展方法允许向已有类型"添加"方法,而无需修改原始类型。

// 扩展方法必须定义在静态类中
public static class StringExtensions
{
    // 为 string 类型添加扩展方法
    // 第一个参数用 this 修饰,表示扩展的目标类型
    public static bool IsEmail(this string str)
    {
        if (string.IsNullOrWhiteSpace(str))
            return false;
        return str.Contains('@') && str.Contains('.');
    }

    public static string Truncate(this string str, int maxLength)
    {
        if (string.IsNullOrEmpty(str)) return str;
        return str.Length <= maxLength ? str : str[..maxLength] + "...";
    }

    public static string Reverse(this string str)
    {
        if (string.IsNullOrEmpty(str)) return str;
        char[] chars = str.ToCharArray();
        Array.Reverse(chars);
        return new string(chars);
    }

    // 泛型扩展方法
    public static bool IsNullOrEmpty<T>(this IEnumerable<T> source)
        => source == null || !source.Any();
}

// 使用扩展方法
public static class ExtensionMethodDemo
{
    public static void Run()
    {
        string email = "user@example.com";
        Console.WriteLine(email.IsEmail());  // True

        string longText = "这是一段很长的文字需要截断显示";
        Console.WriteLine(longText.Truncate(8));  // 这是一段很长的文字...

        string name = "Hello";
        Console.WriteLine(name.Reverse());         // olleH

        List<int> emptyList = new List<int>();
        Console.WriteLine(emptyList.IsNullOrEmpty());  // True
    }
}

6.3 本地函数(Local Function,C# 7.0+)

方法内部可以定义局部函数,只在该方法内可见。

public class QuickSort
{
    public static int[] Sort(int[] array)
    {
        if (array == null || array.Length <= 1)
            return array?.ToArray() ?? Array.Empty<int>();

        var result = array.ToArray();

        // 本地函数
        void QuickSortRecursive(int[] arr, int left, int right)
        {
            if (left >= right) return;

            int Partition(int[] a, int l, int r)
            {
                int pivot = a[r];
                int i = l - 1;
                for (int j = l; j < r; j++)
                {
                    if (a[j] < pivot)
                    {
                        i++;
                        (a[i], a[j]) = (a[j], a[i]);
                    }
                }
                (a[i + 1], a[r]) = (a[r], a[i + 1]);
                return i + 1;
            }

            int pivotIndex = Partition(arr, left, right);
            QuickSortRecursive(arr, left, pivotIndex - 1);
            QuickSortRecursive(arr, pivotIndex + 1, right);
        }

        QuickSortRecursive(result, 0, result.Length - 1);
        return result;
    }
}

// 使用
int[] numbers = { 9, 3, 7, 1, 5, 4, 8, 2, 6 };
int[] sorted = QuickSort.Sort(numbers);
Console.WriteLine(string.Join(", ", sorted));  // 1, 2, 3, 4, 5, 6, 7, 8, 9

6.4 匿名方法与 Lambda 表达式

public class LambdaDemo
{
    public static void Run()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

        // 使用具名方法
        bool IsEven(int n) => n % 2 == 0;
        var evens1 = numbers.FindAll(IsEven);

        // 使用匿名方法(C# 2.0)
        var evens2 = numbers.FindAll(delegate(int n) { return n % 2 == 0; });

        // 使用 Lambda 表达式(C# 3.0+)
        var evens3 = numbers.FindAll(n => n % 2 == 0);

        // Lambda 表达式多语句
        Func<int, int, int> complexCalc = (x, y) =>
        {
            int intermediate = x * x + y * y;
            return (int)Math.Sqrt(intermediate);
        };

        Console.WriteLine(complexCalc(3, 4));  // 5
    }
}

6.5 虚方法、抽象方法与接口方法

// ========== 基类 ==========
public abstract class Shape
{
    // 抽象方法(必须在派生类中实现)
    public abstract double Area();

    // 虚方法(有默认实现,可被重写)
    public virtual string Description()
    {
        return $"这是一个形状,面积: {Area():F2}";
    }

    // 普通方法(不能被重写)
    public void PrintInfo()
    {
        Console.WriteLine(Description());
    }
}

// ========== 派生类 ==========
public class Circle : Shape
{
    public double Radius { get; set; }

    public Circle(double radius) => Radius = radius;

    // 实现抽象方法
    public override double Area() => Math.PI * Radius * Radius;

    // 重写虚方法
    public override string Description()
        => $"圆形(半径={Radius}),面积: {Area():F2}";
}

public class Rectangle : Shape
{
    public double Width { get; set; }
    public double Height { get; set; }

    public Rectangle(double width, double height)
    {
        Width = width;
        Height = height;
    }

    // 实现抽象方法
    public override double Area() => Width * Height;

    // 重写虚方法
    public override string Description()
        => $"矩形({Width}x{Height}),面积: {Area():F2}";
}

// 使用示例(多态)
Shape[] shapes = { new Circle(5), new Rectangle(4, 6) };
foreach (var shape in shapes)
{
    shape.PrintInfo();
}
// 输出:
// 圆形(半径=5),面积: 78.54
// 矩形(4x6),面积: 24.00

总结

概念 关键点
方法定义 访问修饰符 + 返回类型 + 方法名 + 参数 + 方法体
值参数 默认传递方式,值类型复制值,引用类型复制引用
ref 参数 双向传递,传入前必须初始化
out 参数 输出传递,传入前可不初始化,方法内必须赋值
params 参数 可变数量参数,必须是最后一个参数
可选参数 提供默认值,必须放在必需参数之后
命名参数 按名称传参,忽略位置顺序
返回值 void、基本类型、自定义类型、Tuple、IEnumerable、Task 等
方法重载 同名方法,参数列表不同(数量/类型/顺序)
扩展方法 静态类中的静态方法,第一个参数用 this 修饰
本地函数 方法内部定义的函数,只在该方法内可见
表达式体 => 简化单语句方法
0
博主关闭了当前页面的评论