偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

C# 中 const 和 readonly 關(guān)鍵字的區(qū)別和用法

開(kāi)發(fā) 前端
在C#中用于聲明運(yùn)行時(shí)常量,其值可以在聲明時(shí)或構(gòu)造函數(shù)中初始化,之后不可更改(可通過(guò)反射強(qiáng)制修改)。

前言

今天我們一起來(lái)講講 C# 中 const 和 readonly 關(guān)鍵字的區(qū)別和用法。

const 和 readonly 關(guān)鍵字區(qū)別

基本介紹

  • const(常量): 在C#中用于聲明編譯時(shí)常量,其值在編譯時(shí)就必須確定,并且在程序生命周期內(nèi)不可更改。
  • readonly(只讀字段): 在C#中用于聲明運(yùn)行時(shí)常量,其值可以在聲明時(shí)或構(gòu)造函數(shù)中初始化,之后不可更改(可通過(guò)反射強(qiáng)制修改)。

const 和 readonly 異同點(diǎn)

對(duì)比維度

const

readonly

基礎(chǔ)定義

編譯時(shí)常量,值在編譯期確定

運(yùn)行時(shí)常量,值在運(yùn)行時(shí)確定

初始化時(shí)機(jī)

必須在聲明時(shí)初始化

可在聲明時(shí)或構(gòu)造函數(shù)中初始化

支持的數(shù)據(jù)類型

僅支持基元類型(int, float, char, bool等)、string和null引用

支持所有類型(包括自定義類和結(jié)構(gòu)體)

默認(rèn)值要求

必須顯式初始化

不需要顯示初始化,值類型默認(rèn)零值,引用類型默認(rèn)null

性能表現(xiàn)

零開(kāi)銷訪問(wèn)(直接編譯到IL)

微小訪問(wèn)開(kāi)銷(作為實(shí)例/靜態(tài)字段分配內(nèi)存)

線程安全

天然線程安全

實(shí)例字段需注意可見(jiàn)性,靜態(tài)字段線程安全

反射修改

無(wú)法通過(guò)反射修改

可通過(guò)反射強(qiáng)制修改

IL元數(shù)據(jù)標(biāo)記

literal 標(biāo)記

initonly 標(biāo)記

使用場(chǎng)景

聲明常量字段或本地常量,常量可以是數(shù)字、布爾值、字符串或 null 引用等

聲明依賴注入對(duì)象、配置值、運(yùn)行時(shí)計(jì)算值等

const 和 readonly 關(guān)鍵字使用

const 使用

public enum UserRole
    {
        Admin,
        User,
        Guest
    }

    public class ConstAndReadonlyExercise
    {
        // const 初始化
        public const int MaxCount = 999;
        public const UserRole CurrentUserRole = UserRole.Admin;
    }

編譯后 IL 代碼:

  • literal 關(guān)鍵字:標(biāo)記為字面量,值直接嵌入調(diào)用處的 IL。
.field public static literal int32 MaxCount = int32(999) // 0x000003e7

  .field public static literal valuetype 'HelloDotNetGuide.CSharp語(yǔ)法.UserRole' CurrentUserRole = int32(0) // 0x00000000

readonly 使用

// readonly 初始化
 public readonly string _applicationName = "HelloDotNetGuide";

 public ConstAndReadonlyExercise()
 {
     _applicationName = "HelloDotNetGuide_V2";
 }

 // 懶漢式單例模式示例
 private static ConstAndReadonlyExercise? _instance;
 private static readonly object _lockObj = new object();

 public static ConstAndReadonlyExercise Instance
 {
     get
     {
         if (_instance == null)
         {
             lock (_lockObj)
             {
                 _instance ??= new ConstAndReadonlyExercise();
             }
         }
         return _instance;
     }
 }

 /// <summary>
 /// 反射修改 readonly 字段的值
 /// </summary>
 public static void UpdateApplicationNameValue()
 {
     var instance = new ConstAndReadonlyExercise();
     Console.WriteLine($"初始值: {instance._applicationName}");
     // 輸出: 初始值: HelloDotNetGuide_V2

     var field = instance.GetType().GetField("_applicationName");
     field.SetValue(instance, "HelloDotNetGuide_V3");

     Console.WriteLine($"修改后: {instance._applicationName}");
     // 輸出: 修改后: HelloDotNetGuide_V3
 }

編譯后 IL 代碼:

  • initonly 關(guān)鍵字:標(biāo)志被 CLR 識(shí)別為僅構(gòu)造函數(shù)可寫(xiě)約束。
.field public initonly string _applicationName

  .field private static class 'HelloDotNetGuide.CSharp語(yǔ)法.ConstAndReadonlyExercise' _instance
    .custom instance void [System.Runtime]System.Runtime.CompilerServices.NullableAttribute::.ctor(unsigned int8)
      = (01 00 02 00 00 ) // .....
      // unsigned int8(2) // 0x02

  .field private static initonly object _lockObj

  .method public hidebysig specialname rtspecialname instance void
    .ctor() cil managed
  {
    .maxstack 8

    // [25 9 - 25 70]
    IL_0000: ldarg.0      // this
    IL_0001: ldstr        "HelloDotNetGuide"
    IL_0006: stfld        string 'HelloDotNetGuide.CSharp語(yǔ)法.ConstAndReadonlyExercise'::_applicationName

    // [29 9 - 29 42]
    IL_000b: ldarg.0      // this
    IL_000c: call         instance void [System.Runtime]System.Object::.ctor()
    IL_0011: nop

    // [30 9 - 30 10]
    IL_0012: nop

    // [31 13 - 31 54]
    IL_0013: ldarg.0      // this
    IL_0014: ldstr        "HelloDotNetGuide_V2"
    IL_0019: stfld        string 'HelloDotNetGuide.CSharp語(yǔ)法.ConstAndReadonlyExercise'::_applicationName

    // [32 9 - 32 10]
    IL_001e: ret

  } // end of method ConstAndReadonlyExercise::.ctor

  .method public hidebysig static specialname class 'HelloDotNetGuide.CSharp語(yǔ)法.ConstAndReadonlyExercise'
    get_Instance() cil managed
  {
    .maxstack 2
    .locals init (
      [0] bool V_0,
      [1] object V_1,
      [2] bool V_2,
      [3] class 'HelloDotNetGuide.CSharp語(yǔ)法.ConstAndReadonlyExercise' V_3
    )

    // [37 13 - 37 14]
    IL_0000: nop

    // [38 17 - 38 39]
    IL_0001: ldsfld       class 'HelloDotNetGuide.CSharp語(yǔ)法.ConstAndReadonlyExercise''HelloDotNetGuide.CSharp語(yǔ)法.ConstAndReadonlyExercise'::_instance
    IL_0006: ldnull
    IL_0007: ceq
    IL_0009: stloc.0      // V_0

    IL_000a: ldloc.0      // V_0
    IL_000b: brfalse.s    IL_0040

    // [39 17 - 39 18]
    IL_000d: nop

    // [40 21 - 40 36]
    IL_000e: ldsfld       object 'HelloDotNetGuide.CSharp語(yǔ)法.ConstAndReadonlyExercise'::_lockObj
    IL_0013: stloc.1      // V_1
    IL_0014: ldc.i4.0
    IL_0015: stloc.2      // V_2
    .try
    {
      IL_0016: ldloc.1      // V_1
      IL_0017: ldloca.s     V_2
      IL_0019: call         void [System.Threading]System.Threading.Monitor::Enter(object, bool&)
      IL_001e: nop

      // [41 21 - 41 22]
      IL_001f: nop

      // [42 25 - 42 70]
      IL_0020: ldsfld       class 'HelloDotNetGuide.CSharp語(yǔ)法.ConstAndReadonlyExercise''HelloDotNetGuide.CSharp語(yǔ)法.ConstAndReadonlyExercise'::_instance
      IL_0025: brtrue.s     IL_0031
      IL_0027: newobj       instance void 'HelloDotNetGuide.CSharp語(yǔ)法.ConstAndReadonlyExercise'::.ctor()
      IL_002c: stsfld       class 'HelloDotNetGuide.CSharp語(yǔ)法.ConstAndReadonlyExercise''HelloDotNetGuide.CSharp語(yǔ)法.ConstAndReadonlyExercise'::_instance

      // [43 21 - 43 22]
      IL_0031: nop
      IL_0032: leave.s      IL_003f
    } // end of .try
    finally
    {

      IL_0034: ldloc.2      // V_2
      IL_0035: brfalse.s    IL_003e
      IL_0037: ldloc.1      // V_1
      IL_0038: call         void [System.Threading]System.Threading.Monitor::Exit(object)
      IL_003d: nop

      IL_003e: endfinally
    } // end of finally

    // [44 17 - 44 18]
    IL_003f: nop

    // [45 17 - 45 34]
    IL_0040: ldsfld       class 'HelloDotNetGuide.CSharp語(yǔ)法.ConstAndReadonlyExercise''HelloDotNetGuide.CSharp語(yǔ)法.ConstAndReadonlyExercise'::_instance
    IL_0045: stloc.3      // V_3
    IL_0046: br.s         IL_0048

    // [46 13 - 46 14]
    IL_0048: ldloc.3      // V_3
    IL_0049: ret

  } // end of method ConstAndReadonlyExercise::get_Instance

  .method public hidebysig static void
    UpdateApplicationNameValue() cil managed
  {
    .maxstack 3
    .locals init (
      [0] class 'HelloDotNetGuide.CSharp語(yǔ)法.ConstAndReadonlyExercise''instance',
      [1] class [System.Runtime]System.Reflection.FieldInfo 'field'
    )

    // [50 9 - 50 10]
    IL_0000: nop

    // [51 13 - 51 59]
    IL_0001: newobj       instance void 'HelloDotNetGuide.CSharp語(yǔ)法.ConstAndReadonlyExercise'::.ctor()
    IL_0006: stloc.0      // 'instance'

    // [52 13 - 52 68]
    IL_0007: ldstr        "初始值: "
    IL_000c: ldloc.0      // 'instance'
    IL_000d: ldfld        string 'HelloDotNetGuide.CSharp語(yǔ)法.ConstAndReadonlyExercise'::_applicationName
    IL_0012: call         string [System.Runtime]System.String::Concat(string, string)
    IL_0017: call         void [System.Console]System.Console::WriteLine(string)
    IL_001c: nop

    // [55 13 - 55 73]
    IL_001d: ldloc.0      // 'instance'
    IL_001e: callvirt     instance class [System.Runtime]System.Type [System.Runtime]System.Object::GetType()
    IL_0023: ldstr        "_applicationName"
    IL_0028: callvirt     instance class [System.Runtime]System.Reflection.FieldInfo [System.Runtime]System.Type::GetField(string)
    IL_002d: stloc.1      // 'field'

    // [56 13 - 56 61]
    IL_002e: ldloc.1      // 'field'
    IL_002f: ldloc.0      // 'instance'
    IL_0030: ldstr        "HelloDotNetGuide_V3"
    IL_0035: callvirt     instance void [System.Runtime]System.Reflection.FieldInfo::SetValue(object, object)
    IL_003a: nop

    // [58 13 - 58 68]
    IL_003b: ldstr        "修改后: "
    IL_0040: ldloc.0      // 'instance'
    IL_0041: ldfld        string 'HelloDotNetGuide.CSharp語(yǔ)法.ConstAndReadonlyExercise'::_applicationName
    IL_0046: call         string [System.Runtime]System.String::Concat(string, string)
    IL_004b: call         void [System.Console]System.Console::WriteLine(string)
    IL_0050: nop

    // [60 9 - 60 10]
    IL_0051: ret

  } // end of method ConstAndReadonlyExercise::UpdateApplicationNameValue


責(zé)任編輯:武曉燕 來(lái)源: 追逐時(shí)光者
相關(guān)推薦

2009-08-27 10:54:09

C# const和st

2024-02-23 18:04:37

C++const關(guān)鍵字

2024-12-26 00:28:59

C#base?關(guān)鍵字

2015-11-10 16:10:22

C語(yǔ)言StaticConst

2021-07-28 06:53:02

C++Const指針傳遞

2021-08-04 08:33:59

TypeScriptConst Readonly

2009-09-02 09:24:03

C# this關(guān)鍵字

2024-05-29 14:09:00

C#編程this

2009-08-21 14:58:56

C# this關(guān)鍵字

2024-06-04 17:02:38

newC#編程語(yǔ)言

2011-04-21 16:57:56

staticextern

2009-08-13 13:04:29

C# lock關(guān)鍵字

2009-08-06 17:52:23

C#增加that關(guān)鍵字

2009-08-21 14:47:59

C# base關(guān)鍵字

2009-08-26 15:16:29

C# lock關(guān)鍵字

2009-08-13 17:44:34

C# using關(guān)鍵字

2024-01-15 10:41:31

C++關(guān)鍵字開(kāi)發(fā)

2024-12-31 00:05:24

new?關(guān)鍵字C#

2025-01-24 08:32:00

運(yùn)算符C#

2011-05-17 13:04:20

Cconst
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)