【C#】【引用类型】

144 阅读3分钟

引用类型存储的是数据的引用,以下关键字用于声明引用类型:class,interface,delegate,record. C#也提供了下列内置引用类型dynamic,object,string.

内置引用类型

Object

可以将任何类型的值赋给 object 类型的变量。将值类型的变量转换为对象的过程称为装箱。 将 object 类型的变量转换为值类型的过程称为取消装箱。

string类型

string a = "hello";
string b = "h";
b += "ello";

Console.WriteLine(a == b); //True
Console.WriteLine(Object.ReferenceEquals(a,b)); //False

//字符串文本
//1. 原始字符串字面量,至少三个""括起来,不需要转移序列

string message = """
"This is a very important message."
""";
Console.WriteLine(message); // "This is a very important message."

//2.逐字字符串
string source = @"good morning , \a";
Console.WriteLine(source); //good morning , \a

//3. UTF-8字面量
ReadOnlySpan<byte> AuthStringLiteral = "AUTH"u8;

byte[] AuthLiteral = "AUTH"u8.ToArray();

委托类型

delegate 是一种可用于封装命名方法或匿名方法的引用类型。 委托类似于 C++ 中的函数指针。委托用于将方法作为参数传递给其他方法。 事件处理程序就是通过委托调用的方法。

public class Test
{
    //1. 声明 名为 Callback的委托
    public delegate void Callback(string message);
    //2. 为委托创建方法,传递到委托的参数会传递给该方法
    public static void DelegateMethod(string message)
    {
        Console.WriteLine(message);
    }
    public static void Main(String[] args)
    {
        //3. 实例化委托对象
        Callback handler = DelegateMethod;
        handler("hello delegate!");

        //3. 使用lambda表达式分配给委托类型
        Callback handler2 = name => {Console.WriteLine($"Notification received for: {name}");};
        handler2("duckyo"); 

        //3. 声明匿名方法
        Callback handler3 = delegate(string name){Console.WriteLine($"Notification received for: {name}");};
        handler3("biko");
    }
}

动态类型

dynamic 类型表示变量的使用和对其成员的引用绕过编译时类型检查。 改为在运行时解析这些操作。在大多数情况下,dynamic 类型与 object 类型的行为类似。 具体而言,任何非 Null 表达式都可以转换为 dynamic 类型。 dynamic 类型与 object 的不同之处在于,编译器不会对包含类型 dynamic 的表达式的操作进行解析或类型检查。 编译器将有关该操作信息打包在一起,之后这些信息会用于在运行时评估操作。 在此过程中,dynamic 类型的变量会编译为 object 类型的变量。 因此,dynamic 类型只在编译时存在,在运行时则不存在。

class

使用class声明一个类,在C#中仅允许单一继承,但是一个类可以实现多个接口。使用与JAVA类似。

interface

实现接口的任何class,record,struct必须提供接口中定义的成员的实现。

接口不能包含实例状态。 虽然现在允许使用静态字段,但接口中不允许使用实例字段。

interface ISampleInterface
{
    void SampleMethod();
}

class ImplementationClass: ISampleInterface
{
    void ISampleInterface.SampleMethod()
    {
        Console.WriteLine("HELLO INTERFACE");
    }

    static void Main(String[] args)
    {
        ISampleInterface obj = new ImplementationClass();
        obj.SampleMethod();
    }
}

interface IPoint
{
    // Property signatures:
    int X { get; set; }

    int Y { get; set; }

    double Distance { get; }
}

class Point : IPoint
{
    // Constructor:
    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    // Property implementation:
    public int X { get; set; }

    public int Y { get; set; }

    // Property implementation
    public double Distance =>
       Math.Sqrt(X * X + Y * Y);
}

class MainClass
{
    static void PrintPoint(IPoint p)
    {
        Console.WriteLine("x={0}, y={1}", p.X, p.Y);
    }

    static void Main()
    {
        IPoint p = new Point(2, 3);
        Console.Write("My Point: ");
        PrintPoint(p);
    }
}
// Output: My Point: x=2, y=3

record

深入理解C#中的record类型 - 知乎 (zhihu.com)