C#知识整理-类型

值类型和引用类型是c#类型的两个主要类别。他们都继承自System.Object。使用struct关键字定义的类型是值类型,使用class关键字定义的类型是引用类型。
它们的关系如下图:

 

值类型
  • 基本数据类型:int, double, float, bool, char, byte, sbyte, short, ushort, uint, long, ulong,datetime。
  • 结构体(Struct):struct。
  • 枚举(Enum):enum。
  • 值元组(Tuple):(decimal, int) t1=(1.1m, 3)
  • 可为空的值类型(Nullable):Nullable或T?
特点:
  1. 存储位置: 值类型存储在栈(Stack)上。
  2. 内存分配: 每个值类型变量都有自己的内存空间,因此它们是独立的。
  3. 赋值操作: 当值类型变量被赋值给另一个变量时,会创建该值的一个副本。
  4. 内存效率: 由于值类型存储在栈上,它们通常比引用类型更快。
  5. 默认值: 值类型变量在声明时必须被初始化,否则会报错。
引用类型
  • 基本数据类型:string, dynamic, object。
  • 类(Class):class。
  • 接口(Interface):interface。
  • 数组(Array):[]。
  • 委托(Delegate):delegate。
  • 记录 (record): record。
特点:
  1. 存储位置: 引用类型存储在堆(Heap)上,而引用本身存储在栈上。
  2. 内存分配: 引用类型的变量指向同一块内存地址,因此它们可以共享数据。
  3. 赋值操作: 当引用类型变量被赋值给另一个变量时,两个变量将引用同一块内存地址。
  4. 内存效率: 由于引用类型需要额外的间接寻址,它们通常比值类型慢。
  5. 默认值: 引用类型变量在声明时如果没有被初始化,它们会被自动初始化为null。
 
一些类型的初始化
复制代码
internal class Program
{
    static void Main(string[] args)
    {
        //值类型
        int iA=10; 
        int iB=iA;
        iB = 100;
        Console.WriteLine(iA);
        Console.WriteLine(iB);
        /*
         * iA=10
         * iB=100
         */
        //测试溢出
        short iC = 32767;
        Console.WriteLine(iC); //32767
        iC++;
        Console.WriteLine(iC); //-32768

        double a = 0.1f;
        double b = 0.2f;
        double c = a + b;
        Console.WriteLine($"a:{a}, b:{b}, c:{c}");
        /*
         * a:0.10000000149011612, b:0.20000000298023224, c:0.30000000447034836
         * double 的精度问题可以
         */

        decimal d = 0.1m;
        decimal e = 0.2m;
        decimal f = e + d;
        Console.WriteLine($"d:{d}, e:{e}, f:{f}");
        /*
         * d: 0.1, e: 0.2, f: 0.3
         */

        var charA = 'A';
        Console.WriteLine($"chatA:{charA}, type: {charA.GetType()}");
        /*chatA:A, type: System.Char*/

        (decimal, int) t = (1.1m, 3);
        Console.WriteLine(t);//(1.1, 3)
        Console.WriteLine($"{t.Item1}:{t.Item2}");//1.1:3

        bool? bA= null;
        Console.WriteLine(bA.HasValue);//False

        //引用类型
        string sA = "10";
        string sB = sA;
        sB = "100";//这里新建了一个对象 "100"
        Console.WriteLine(sA);//10
        Console.WriteLine(sB);//100
        testClass clsA = new testClass() { i = 10, str = "10" };
        var clsB=clsA;//新建一个对象clsB,类中所有的值都是和clsA来自同一个引用
        clsB.i = 100;
        clsB.str = "100";
        Console.WriteLine(clsA);//i:100,str:100
        Console.WriteLine(clsB);//i:100,str:100

        Console.ReadLine();
    }
}

public class testClass
{
    public int i;
    public string str;

    public override string ToString()
    {
        return $"i:{i},str:{str}";
    }
}
复制代码

 

posted @   Terry841119  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示