1. 字段与属性的本质区别

字段(Field)是类或结构体中存储数据的变量,而属性(Property)是访问字段的封装方式。

核心区别

  • 字段是数据存储单元,属性是数据访问的接口

  • 字段可直接访问,属性通过 get/set 方法控制访问逻辑

  • 属性支持数据验证、计算和变更通知等高级功能

public class Person
{
    // 私有字段(数据存储)
    private string _name;
    private int _age;
​
    // 自动实现属性(简化语法)
    public string Address { get; set; }
​
    // 带验证逻辑的属性
    public string Name
    {
        get => _name;
        set
        {
            if (string.IsNullOrEmpty(value))
                throw new ArgumentException("Name cannot be empty");
            _name = value;
        }
    }
​
    // 计算属性
    public int BirthYear
    {
        get => DateTime.Now.Year - _age;
    }
​
    // 构造函数初始化
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
}
2. 访问修饰符详解

C# 提供了 5 种访问修饰符,控制成员的可见性:

修饰符 访问权限描述
public 无访问限制
private 仅在定义类型内部可访问
protected 在定义类型及其派生类中可访问
internal 在当前程序集(项目)内可访问
protected internal 同时满足 protectedinternal
3. 函数(静态方法)与方法的差异

在 C# 中,"函数" 通常指静态方法,而 "方法" 指实例方法:

public static class MathHelper
{
    // 静态方法(函数):不依赖实例
    public static double CalculateCircleArea(double radius)
    {
        return Math.PI * radius * radius;
    }
}
​
public class Calculator
{
    private int _memoryValue;
​
    // 实例方法:依赖对象状态
    public void AddToMemory(int value)
    {
        _memoryValue += value;
    }
​
    // 静态方法:不依赖对象状态
    public static int Add(int a, int b) => a + b;
}
​
// 调用示例
double area = MathHelper.CalculateCircleArea(5);
int sum = Calculator.Add(3, 4);
​
Calculator calc = new Calculator();
calc.AddToMemory(10); // 访问实例方法
4. 结构体(Struct)与类(Class)的本质区别

结构体是值类型,类是引用类型,二者的核心差异体现在内存分配和使用方式上:

// 值类型:结构体
public struct Point
{
    public double X { get; set; }
    public double Y { get; set; }
​
    // 结构体构造函数必须初始化所有属性
    public Point(double x, double y)
    {
        X = x;
        Y = y;
    }
​
    // 方法:计算到原点的距离
    public double DistanceToOrigin() => Math.Sqrt(X * X + Y * Y);
}
​
// 引用类型:类
public class ComplexNumber
{
    public double Real { get; set; }
    public double Imaginary { get; set; }
​
    public ComplexNumber(double real, double imaginary)
    {
        Real = real;
        Imaginary = imaginary;
    }
​
    // 方法:复数加法
    public ComplexNumber Add(ComplexNumber other)
    {
        return new ComplexNumber(Real + other.Real, Imaginary + other.Imaginary);
    }
}
​
// 使用差异
Point p1 = new Point(3, 4);
Point p2 = p1; // 值复制
p2.X = 5;      // 不影响p1
​
ComplexNumber c1 = new ComplexNumber(1, 2);
ComplexNumber c2 = c1; // 引用复制
c2.Real = 3;           // 同时修改c1和c2
5. 继承与多态的实现

C# 支持单继承和多态,通过 virtualoverrideabstract 关键字实现:

// 抽象基类
public abstract class Shape
{
    public string Color { get; set; }
​
    protected Shape(string color)
    {
        Color = color;
    }
​
    // 抽象方法:必须在子类中实现
    public abstract double Area();
​
    // 虚方法:可在子类中重写
    public virtual string GetInfo()
    {
        return $"Color: {Color}, Area: {Area():F2}";
    }
}
​
// 具体子类
public class Circle : Shape
{
    public double Radius { get; set; }
​
    public Circle(double radius, string color) : base(color)
    {
        Radius = radius;
    }
​
    // 实现抽象方法
    public override double Area() => Math.PI * Radius * Radius;
​
    // 重写虚方法
    public override string GetInfo()
    {
        return $"Circle - {base.GetInfo()}";
    }
}
​
public class Rectangle : Shape
{
    public double Width { get; set; }
    public double Height { get; set; }
​
    public Rectangle(double width, double height, string color) : base(color)
    {
        Width = width;
        Height = height;
    }
​
    public override double Area() => Width * Height;
​
    public override string GetInfo()
    {
        return $"Rectangle - {base.GetInfo()}";
    }
}
​
// 多态示例
Shape[] shapes = new Shape[]
{
    new Circle(5, "Red"),
    new Rectangle(4, 6, "Blue")
};
​
foreach (var shape in shapes)
{
    Console.WriteLine(shape.GetInfo());
    // 输出:
    // Circle - Color: Red, Area: 78.54
    // Rectangle - Color: Blue, Area: 24.00
}
6. 接口的设计与实现

接口定义了行为契约,支持多实现和依赖倒置原则:

// 定义多个接口
public interface IRenderable
{
    void Render();
}
​
public interface IAnimatable
{
    void Animate();
}
​
// 实现多个接口
public class Button : IRenderable, IAnimatable
{
    public string Text { get; set; }
​
    public Button(string text)
    {
        Text = text;
    }
​
    // 显式实现接口方法
    void IRenderable.Render()
    {
        Console.WriteLine($"Rendering button: {Text}");
    }
​
    // 隐式实现接口方法
    public void Animate()
    {
        Console.WriteLine("Animating button...");
    }
}
​
// 接口作为参数类型(依赖注入)
public class UIManager
{
    public void DrawUI(IRenderable element)
    {
        element.Render();
    }
}
​
// 使用示例
Button btn = new Button("Submit");
UIManager manager = new UIManager();
manager.DrawUI(btn); // 输出: Rendering button: Submit

关键补充知识

1.密封类与方法:禁止继承或重写
public sealed class FinalClass // 密封类不能被继承
{
    public void DoSomething() { }
}
​
public class BaseClass
{
    public virtual void Method() { }
}
​
public class DerivedClass : BaseClass
{
    public sealed override void Method() { } // 密封此方法,禁止进一步重写
}
2.接口默认实现(C# 8.0+)
public interface ILogger
{
    // 默认实现
    void Log(string message) => Console.WriteLine($"[INFO]: {message}");
    
    // 抽象方法(必须实现)
    void LogError(string error);
}
​
public class ConsoleLogger : ILogger
{
    public void LogError(string error) => Console.WriteLine($"[ERROR]: {error}");
    
    // 可以选择性重写默认方法
    public void Log(string message) => Console.WriteLine($"[CUSTOM]: {message}");
}
3.扩展方法:为现有类型添加新方法
public static class StringExtensions
{
    public static bool IsPalindrome(this string str)
    {
        if (string.IsNullOrEmpty(str)) return false;
        int left = 0;
        int right = str.Length - 1;
        while (left < right)
        {
            if (str[left] != str[right]) return false;
            left++;
            right--;
        }
        return true;
    }
}
​
// 使用扩展方法
string test = "radar";
bool result = test.IsPalindrome(); // true
4.静态类与静态构造函数
public static class Configuration
{
    public static string ApiKey { get; private set; }
    public static int Timeout { get; private set; }

    // 静态构造函数(自动调用,且只调用一次)
    static Configuration()
    {
        ApiKey = Environment.GetEnvironmentVariable("API_KEY") ?? "default_key";
        Timeout = int.TryParse(Environment.GetEnvironmentVariable("TIMEOUT"), out int timeout) 
                  ? timeout : 3000;
    }
}
5.抽象类:包含抽象方法的类,不能实例化
public abstract class Shape {
    public abstract double Area(); // 抽象方法
}
6.密封类:禁止被继承
public sealed class FinalClass { } // 不能被继承
7.接口默认实现(C# 8.0+):
public interface ILogger {
    void Log(string message) => Console.WriteLine($"[Log]: {message}");
}
8.扩展方法:为现有类型添加方法
public static class StringExtensions {
    public static bool IsNullOrEmpty(this string str) {
        return string.IsNullOrEmpty(str);
    }
}

核心区别总结

概念 类型 继承规则 内存分配 适用场景
函数 静态方法 方法区 工具类、纯计算逻辑
结构体 值类型 不可继承,可实现接口 栈或对象内 轻量数据(坐标、时间)
引用类型 单继承,支持多接口 复杂对象(用户、订单)
方法 类的成员 可重写、重载 随对象或类型 对象行为的具体实现
继承 类的关系 单继承(每个类一个父类) 共享父类成员 代码复用、多态
接口 契约 可多实现 无(仅定义规范) 定义行为、解耦组件
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐