引用类型存储的是数据的引用,以下关键字用于声明引用类型: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