深入浅出C#(C#指南)

类和对象

类是C#最基本的数据类型,类是一种数据结构,能在一个单元中将状态(字段,可以理解为变量)和操作(方法和其他函数成员)结合起来。类为动态创建的类实例(即对象)提供了定义。类支持继承和派生机制。

新类使用类声明进行创建。 类声明的开头是标头,指定了类的特性和修饰符、类名、基类(若指定)以及类实现的接口。 标头后面是类主体,由在分隔符 { 和 } 内编写的成员声明列表组成。

public class Point
{
    public int x, y;
    public Point(int x, int y) 
    {
        this.x = x;
        this.y = y;
    }
}

类实例是使用 new 运算符进行创建,此运算符为新实例分配内存,调用构造函数来初始化实例,并返回对实例的引用。

Point p1 = new Point(0, 0);
Point p2 = new Point(10, 20);

当无法再访问对象时,对象占用的内存会被自动回收。 既没必要,也无法在 C# 中显式解除分配对象。

成员

类的成员要么是静态成员,要么是实例成员,静态成员属于类,实例成员属于对象
类可以包含的成员类型为常量、字段、方法、属性、索引器、事件、运算符、构造函数、终结器、类型。

可访问性

按照访问权限分为以下五种:

  1. public:访问不受限
  2. protect:只能访问此类或此类的派生类
  3. internal:访问限于当前程序集(.exe,.dll等)
  4. protected internal:访问限于包含类或包含类的派生类
  5. private:只能访问此类

类型参数

类定义可能会按如下方式指定一组类型参数:在类名后面用尖括号括住类型参数名称列表。 然后,可以在类声明的主体中使用类型参数来定义类成员。 在以下示例中,Pair 的类型参数是 TFirst 和 TSecond:

public class Pair<TFirst,TSecond>
{
    public TFirst First;
    public TSecond Second;
}

声明为需要使用类型参数的类类型被称为泛型类类型。 结构、接口和委托类型也可以是泛型。 使用泛型类时,必须为每个类型参数提供类型自变量:

Pair<int,string> pair = new Pair<int,string> { First = 1, Second = "two" };
int i = pair.First;     // TFirst is int
string s = pair.Second; // TSecond is string

字段

字段是与类或类实例相关联的变量。

使用静态修饰符声明的字段定义的是静态字段。 静态字段只指明一个存储位置。 无论创建多少个类实例,永远只有一个静态字段副本。

不使用静态修饰符声明的字段定义的是实例字段。 每个类实例均包含相应类的所有实例字段的单独副本。

方法

方法是实现对象或类可执行的计算或操作的成员。 静态方法是通过类进行访问。 实例方法是通过类实例进行访问。

方法可能具有参数列表,用于表示传递给方法的值或变量引用;并具有返回类型,用于指定方法计算并返回的值的类型。 如果方法未返回值,则其返回类型为 void。

方法可能也包含一组类型参数,必须在调用方法时指定类型自变量,这一点与类型一样。 与类型不同的是,通常可以根据方法调用的自变量推断出类型自变量,无需显式指定。

在声明方法的类中,方法的签名必须是唯一的。 方法签名包含方法名称、类型参数数量及其参数的数量、修饰符和类型。 方法签名不包含返回类型。

参数

参数用于将值或变量引用传递给方法。 方法参数从调用方法时指定的自变量中获取其实际值。 有四类参数:值参数、引用参数、输出参数和参数数组。

值参数用于传递输入自变量。 值参数对应于局部变量。

引用参数用于按引用传递自变量。 为引用参数传递的自变量必须是具有明确值的变量,并且在方法执行期间,引用参数指明的存储位置与自变量相同。 引用参数使用 ref 修饰符进行声明。 下面的示例展示了如何使用 ref 参数。

using System;
class RefExample
{
    static void Swap(ref int x, ref int y) 
    {
        int temp = x;
        x = y;
        y = temp;
    }
    public static void SwapExample() 
    {
        int i = 1, j = 2;
        Swap(ref i, ref j);
        Console.WriteLine($"{i} {j}");    // Outputs "2 1"
    }
}

输出参数用于按引用传递自变量。 输出参数与引用参数类似,不同之处在于,不要求向调用方提供的自变量显式赋值。 输出参数使用 out 修饰符进行声明。

using System;
    class OutExample
    {
        static void Divide(int x, int y, out int result, out int remainder) 
        {
            result = x / y;
            remainder = x % y;
        }
        public static void OutUsage() 
        {
            Divide(10, 3, out int res, out int rem);
            Console.WriteLine("{0} {1}", res, rem); // Outputs "3 1"
        }
    }
}

参数数组允许向方法传递数量不定的自变量。 参数数组使用 params 修饰符进行声明。 参数数组只能是方法的最后一个参数,且参数数组的类型必须是一维数组类型。 @System.Console 类的 Write 和 WriteLine 方法是参数数组用法的典型示例。 它们的声明方式如下:

public class Console
{
    public static void Write(string fmt, params object[] args) { }
    public static void WriteLine(string fmt, params object[] args) { }
    // ...
}

方法主体和局部变量

方法主体指定了在调用方法时执行的语句。

方法主体可以声明特定于方法调用的变量。 此类变量称为局部变量。 局部变量声明指定了类型名称、变量名称以及可能的初始值。

虚方法、重写方法和抽象方法

如果实例方法声明中有 virtual 修饰符,可以将实例方法称为“虚方法”。 如果没有 virtual 修饰符,可以将实例方法称为“非虚方法”。

抽象方法是没有实现代码的虚方法。 抽象方法使用 abstract 修饰符进行声明,只能在同样声明了 abstract 的类中使用。 必须在所有非抽象派生类中重写抽象方法。

方法重载

借助方法重载,同一类中可以有多个同名的方法,只要这些方法具有唯一签名即可。 编译如何调用重载的方法时,编译器使用重载决策来确定要调用的特定方法。 重载决策查找与自变量最匹配的方法;如果找不到最佳匹配项,则会报告错误。类似C++中的函数重载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值