C#中常见类型以及传递方式

C#的值类型和引用类型

值类型

定义

值类型(value types)是存储在栈上(stack)而不是堆上(heap)的数据类型。值类型直接包含其数据,赋值操作会复制数据本

常见的值类型

1.基本数据类型
  • int:32位整数。
  • long:64位整数。
  • short:16位整数。
  • byte:8位无符号整数。
  • uint:32位无符号整数。
  • ulong:64位无符号整数。
  • ushort:16位无符号整数.
  • sbyte:8位有符号整数。
  • float:32位浮点数。
  • double:64位浮点数.
  • decimal:128位高精度小数。
2.字符类型

 char:16位 Unicode 字符。

3.布尔类型

 bool:表示真 (true) 或假 (false)。

4.结构体类型

例如 DateTimeTimeSpanPointComplex 等。这些是用户定义的值类型。

定义

结构体类型(struct)是C#中的一种数据类型,用于定义一个值类型的数据结构。与类(class)不同,结构体是值类型,意味着它们存储数据的实际值,而不是数据的引用。结构体在内存中通常分配在栈上,具有轻量级和高效的特点。结构体的主要用途是表示简单的数据结构,如点、矩形、时间等。它们不支持继承,但可以实现接口,并且无法定义显式的无参构造函数。

示例

值类型的变量直接包含数据,而不是数据的引用。赋值操作会将数据的副本传递给新的变量。

struct Point
{
    public int X;
    public int Y;
}

Point p1 = new Point { X = 10, Y = 20 };
Point p2 = p1; // 这里p2是p1的副本
p2.X = 30;
Console.WriteLine(p1.X); // 输出 10,p1的值没有改变

5.枚举类型
定义

例如 DayOfWeekConsoleColor 等。枚举类型是由用户定义的一组命名的常数

枚举的特点

1.默认值:枚举中的第一个成员的默认值为0,后续成员的值依次递增。你可以显式指定每个成员的值。

2.基础类型:默认为int,但你可以指定其他整型类型(如byteshortlong等)作为基础类型。

enum DayOfWeek : byte {

Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday

}

3.使用枚举:枚举类型可以用作变量类型,赋值给枚举变量,进行比较和操作

DayOfWeek today = DayOfWeek.Monday;
//为today定义一个初始值 
if (today == DayOfWeek.Monday) 
{ 
Console.WriteLine("Today is Monday."); 
}

4.可以将枚举值转换为其基础类型的值,或将整型值转换为枚举类型。

int dayValue = (int)DayOfWeek.Wednesday; // dayValue = 3
DayOfWeek day = (DayOfWeek)3; // day = DayOfWeek.Wednesday

5.使用Enum类的方法

Enum类提供了一些方法,用于操作和查询枚举值,例如Enum.GetValuesEnum.GetNames

foreach (DayOfWeek day in Enum.GetValues(typeof(DayOfWeek)))
{
    //Enum.GetValues 是一个静态方法,用于获取指定枚举类型的所有值
    Console.WriteLine(day);
}

引用类型

1.class

2.delegate(用于声明委托)

3.interface(接口)

定义

接口可以包含方法、属性、事件和索引器的声明,但不能包含字段、构造函数或实现这些成员的代码。它们的主要作用是定义类或结构体必须实现的一组成员。

使用接口的基本示例

定义一个接口

public interface IShape
{
    double Area(); // 方法声明
    double Perimeter { get; } // 属性声明
}

实现接口的类

public class Rectangle : IShape
{
    public double Width { get; set; }
    public double Height { get; set; }

    // 实现接口的方法
    public double Area()
    {
        return Width * Height;
    }

    // 实现接口的属性
    public double Perimeter
    {
        get { return 2 * (Width + Height); }
    }
}

使用接口

IShape shape = new Rectangle { Width = 5, Height = 10 };
Console.WriteLine($"Area: {shape.Area()}");
Console.WriteLine($"Perimeter: {shape.Perimeter}");
注意点

注意点

  1. 接口实现

    • 类可以实现多个接口,这使得 C# 支持多重继承。
    • 接口的实现必须包括接口中声明的所有成员。
  2. 接口成员的访问修饰符

    • 接口中的所有成员默认为 public,且接口成员不能有访问修饰符。
    • 实现接口的类中的成员必须是 public,以确保它们对外部代码可见。
  3. 接口不能包含实现

    • 接口不能包含方法体或字段,只能声明成员。
    • 从 C# 8.0 开始,接口可以包含具有默认实现的方法,但这不是强制的。
  4. 接口的多重实现

    • 一个类可以实现多个接口,但接口之间不允许有任何成员实现的冲突。
    • 当多个接口有相同的方法或属性时,类只需实现一次即可。
  5. 接口与抽象类的区别

    • 抽象类可以包含实现和状态(字段),而接口只能包含声明。
    • 抽象类可以提供部分实现,并可以包含构造函数。

4.array

5.object

6.string

值传递和引用传递

值传递

系统首先为被调用方法的形参分配内存空间,并将实参的值按位置一一对应地复制给形参,此后,被调用方法中形参值得任何改变都不会影响到相应的实参。也就是会在栈上多创建一个相同的变量。

引用传递

系统不是将实参本身的值复制后传递给形参,而是将其引用值(即地址值)传递给形参,因此,形参所引用的该地址上的变量与传递的实参相同,方法体内相应形参值得任何改变都将影响到作为引用传递的实参

C#中参数传递 ref 与 out 的区别

1.ref

用途:允许在方法中修改参数的值,调用方法前参数必须已初始化

特点:ref可以把值传到方法里,也可以把值传到方法外

public void UpdateValue(ref int number)
{
    number = 10;
}

int x = 5;
UpdateValue(ref x); // x 现在是 10

2.out

用途:用于方法中返回多个值,调用方法前参数不需要初始化,但必须在方法内被赋值.

特点:out只可以把值传到方法外 

public void InitializeValue(out int number)
{
    number = 10; // 必须赋值
}

int x;
InitializeValue(out x); // x 现在是 10

3.String特殊类型

符串赋值操作也是复制引用,但不改变原始字符串对象的内容

想在方法内改变一个字符串的内容并让这些更改反映到调用者那里,需要使用 refout 关键字

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值