C#学习笔记 基础部分

C#程序由命名空间、类、结构、接口等组成,Main方法是入口点。类型系统包括强类型、内置类型(如值类型和引用类型)、自定义类型和泛型。面向对象特性涉及类、继承、多态。同时,文章介绍了异常处理和错误管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 程序结构

C# 程序由一个或多个文件组成。每个文件均包含零个或多个命名空间。一个命名空间包含类、结构、接口、枚举、委托等类型或其他命名空间。

using System;
Console.WriteLine("Hello world!");
namespace Yourspace{
    class YourClass{

    }
    struct YourStruct{

    }
    interface IYourInterface{

    }
    delegate int YourDelegate();
    enum YourEnum{

    }
    namespace YourNestedNamespace{
        struct YourStruct{

        }
    }
}

Main方法是C#应用程序的入口点。

2. 类型系统

C#是一种强类型语言,在变量声明中指定类型,或者使用var关键字让编译器推断类型。

float temperature;
var limit = 3;
2.1 内置类型

包括值类型和引用类型

  • 值类型:bool, byte, sbyte, char, decimal, double, float, int, uint, nint, nuint, long, ulong, short, ushort
    值类型分为两类:structenum
    内置的数值类型是结构,具有可访问的字段和方法
byte b = byte.MaxValue;
  • 引用类型:object, string, dynamic
2.2 自定义类型
2.3 通用类型系统
  1. 支持继承原则
  2. CTS(通用继承原则)中的每种类型被定义为值类型或引用类型
2.4 命名空间
System.Console.WriteLine("Hello World!");

System是一个命名空间,Console是该命名空间的一个类

2.5 类简介

定义为class的类型是引用类型

public class Customer{

}
Customer object1 = new Customer();  //create an object

类继承:

public class Manager:Employee{

}
using System;
public class Person{
    public Person(){
        Name = 'unknown';
    }

    public Person(string name){
        Name = name;
    }

    //auto-implemented readonly property
    public string Name { get; }

    public override string ToString(){
        return Name;
    }
}

class TestPerson{
    static void Main(){
        ver person = new Person();
        Console.WriteLine(person1.Name);
    }
}

2.6 接口

接口包含非抽象class或struct必须实现的一组相关功能的定义。

interface IEquatable<T>{
    bool Equals(T obj);
}

接口名称必须是有效的 C# 标识符名称。 按照约定,接口名称以大写字母 I 开头。
接口可以包含实例方法、属性、事件、索引器或这四种成员类型的任意组合。

2.7 泛型
public class GenericList<T>{
    public void Add(T input){ }
}
class TestGenericList{
    private class ExampleClass{}
    static void Main(){
        GenericList<int> list1 = new GenericList<int>();
        list1.Add(1);

        GenericList<string> list2 = new GenericList<string>();
        list2.Add("");

        GenericList<ExampleClass> list3 = new GenericList<ExampleClass>();
        list3.Add(new ExampleClass());
    }
}

使用泛型类型可以最大限度的重用代码、保护类型安全性以及提高性能。

2.8 匿名类型

匿名类型可用来将一组只读属性封装到单个对象中,无需首先显示定义一个类型。

var v = new { Amount = 108, Message = 'hello' };
Console.WriteLine(v.Amount + v.Message);

3 面向对象的编程

C#没有全局变量和方法。

3.1 对象

类或结构定义的作用类似于蓝图,指定该类型可以进行哪些操作。

  1. 结构实例与类实例
    由于类是引用类型,因此类对象的变量引用该对象在托管堆上的地址。类的实例是使用new运算符创建的。

    public class Person{
        public string Name { get; set; }
        public int Age {get; set; }
        public Person(string name, int age){
            Name = name;
            Age = age;
        }
    }
    
    class Program{
        static void Main(){
            Person person1 = new Person("Leopold", 6);
            Console.WriteLine("person1 Name = {0} Age={1}", person1.Name, person1.Age);
        }
        Person person2 = person1;
    
        person2.Name = "Molly";
        person2.Age = 16;
    }
    

    如果将同一类型的第二个变量分配给第一个变量,则两个变量都引用该地址的对象。
    结构则是值类型,因此结构对象的变量具有整个对象的副本。结构的实例也可以使用new运算符来创建,但不是必须。

    public struct Person{
        // ...
    }
    Person p2 = p1;
    

    p1,p2的内存在线程堆栈上进行分配,该内存随声明它的类型或方法一起回收。

  2. 对象标识与值相等性
    两个变量是否表示内存中的同一对象,还是想知道这两个对象的一个或多个字段的值是否相等。
    确定两个类实例是否引用内存的同一位置:

if(p2.Equals(p1)){
    Console.WriteLine("p2 and p1 have the same values");
}
3.2 继承

成员被继承的类称为“基类”,继承这些成员的类称为“派生类”。

  1. 抽象方法和虚方法
    基类将方法声明为virtual时,派生类可以使用其自己的实现override该方法。
3.3 多形性
public class Shape{

    public int X {get; private set;}
    public int Y {get; private set;}
    public int Height {get; set;}
    public int Width {get; set;}

    public virtual void Draw(){
        Console.WriteLine("Performing base class drawing tasks");
    }
}

public class Circle: Shape{
    public override void Draw(){
        Console.WriteLine("Drawing a circle");
        base.Draw();
    }
}

public class Rectangle: Shape{
    public override void Draw(){
        Console.WriteLine("Drawing a rectangle");
        base.Draw();
    }
}

public class Triangle: Shape{
    public override void Draw(){
        // 
    }
}

当派生类从基类继承时,它包括基类的所有成员。基类中声明的所有行为都是派生类的一部分。这使派生类的对象能够被视为基类的对象。

  • 派生类可以重写基类中的虚拟成员,并定义新行为
  • 派生类可能会继承最接近的基类方法而不重写方法

4 功能技术

4.1 模式匹配
int? maybe = 12;
if(maybe is int number){
    //
}else{
    //
}

上述代码使声明模式,用于测试变量类型并将其分配给新变量。

string message = "This is not the null string";

if(message is not null){
    //...
}
4.3 析构元组和其他类型
var (name, address, city, zip) = contact.GetAddressInfo();
(string ciy, int poputation, double area) = QueryCityData("New York City");
var (_,_,_, pol1,_,pol2) = QueryCityData("New York City");

5 异常和错误

在许多情况下,异常并不是由代码直接调用的方法抛出,而是由调用堆栈中再往下的另一方法抛出。

5.1 使用异常
class CustomException: Exception{
    public CustomException(string message){

    }
}
private static void TestThrow(){
    throw new CustomException("Custom exception in TestThrow()");
}
try{
    TestThrow();
}
catch (CustomException ex){
    System.Console.WriteLine(ex.ToString());
}
5.2 异常处理

finally块让你可以清理再try块中所执行的操作。无论是否会引发异常或者找到匹配异常类型的catch块,finally块都将始终运行。

FileStream? file = null;
FileInfo fileinfo = new System.IO.FileInfo("./file.txt");
try{
    file = fileInfo.OpenWrite();
    file.WriteByte(0xF);
}
finally{
    //Check for null because OpenWrite might have failed
    file?.Close();
}
5.3 创建和引发异常

异常用于指示在运行程序时发生了错误。此时将创建一个描述错误的异常对象,然后使用throw关键字引发。

public class InvalidDepartmentException:Exception{
    public InvalidDepartmentException():base(){}
    public InvalidDepartmentException(string message):base(message){}
    public InvalidDepartmentException(string message,Exception inner):base(message, inner){}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值