当前位置: 首页 > news >正文

C# sealed 、GetType、序列化static

一、GetType()

获取对象的运行时类型(返回 Type

   public  static class Program
   {
       /// <summary>
       /// 应用程序的主入口点。
       /// </summary>
       [STAThread]
       static void Main()
       {

           int num = 10;
           string text = "abcd";
           double pi = 3.1415925;
           Console.WriteLine(num.GetType());   // 输出:System.Int32
           Console.WriteLine(text.GetType());  // 输出:System.String
           Console.WriteLine(pi.GetType());    // 输出:System.Double

           Console.ReadLine();

           Application.EnableVisualStyles();
           Application.SetCompatibleTextRenderingDefault(false);
         //  Application.Run(new Form1());
       }

 

typeof() vs. GetType() 

            int num = 10;
            string text = "abcd";
            double pi = 3.1415925;
            //Console.WriteLine(num.GetType());   // 输出:System.Int32
            //Console.WriteLine(text.GetType());  // 输出:System.String
            //Console.WriteLine(pi.GetType());    // 输出:System.Double




            Type type1 = typeof(int) ;  // 编译的时候确定
            Type  type2= num.GetType();  // 运行的时候确定

            Console.WriteLine(type1 == type2);  // 输出:True

结论

  • typeof(T) 用于在编译时获取类型,不需要实例。
  • obj.GetType() 用于在运行时获取对象的真实类型,需要实例。

 GetType() 与 继承

如果类有继承,GetType() 返回实际子类的类型。

class Parent { }
class Child: Parent { }
public  static class Program
{
    /// <summary>
    /// 应用程序的主入口点。
    /// </summary>
    [STAThread]
    static void Main()
    {

        Parent obj=new Child();
        Console.WriteLine(obj.GetType()); // 输出:Child




        Console.ReadLine();

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
      //  Application.Run(new Form1());
    }

说明

  • obj编译时类型Parent,但 GetType() 返回 Child,因为 obj 实际是 Child 类型的实例。

GetType() 获取类的详细信息

可以使用 GetType() 获取类的详细信息,如属性、方法等:


    class Sample
    {
        public int Number { get; set; }
        public void SayHello() => Console.WriteLine("Hello");
    }

    public  static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {

            Sample obj = new Sample();
            Type type = obj.GetType();  // Sample

            Console.WriteLine($"类名: {type.Name}");
            Console.WriteLine($"命名空间: {type.Namespace}");

            Console.WriteLine("属性列表:");
            foreach (var prop in type.GetProperties())
            {
                Console.WriteLine($"- {prop.Name} ({prop.PropertyType})");
            }

            //- Number (System.Int32)

            Console.WriteLine("方法列表:");
            foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Instance))
            {
                Console.WriteLine($"- {method.Name}");
            }

            // SayHello



            //Parent obj=new Child();
            //Console.WriteLine(obj.GetType()); // 输出:Child








            Console.ReadLine();

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
          //  Application.Run(new Form1());
        }

总结 

 GetType() 获取字段方法


    class Sample
    {
        public int PublicField = 42;
        private string PrivateField = "Secret";

        public static int StaticField = 99; // 静态字段(不会被获取)
        public static string  StaticField2 = "hello"; // 静态字段(不会被获取)
    }

    public  static class Program
    {

        [STAThread]
        static void Main()
        {
            Sample obj = new Sample();
            Type type = obj.GetType();

            #region   属性字段

            FieldInfo[] fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);

            Console.WriteLine("实例字段列表:");
            foreach (var field in fields)
            {
                Console.WriteLine($"- {field.Name} (类型: {field.FieldType}, 值: {field.GetValue(obj)})");
            }
            #endregion

            Console.WriteLine("---------------------------------------------------------------");

            #region  获取静态字段

            FieldInfo[] staticFields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
            foreach (var field in staticFields)
            {
                Console.WriteLine($"- {field.Name} (类型: {field.FieldType}, 值: {field.GetValue(obj)})");
            }
            #endregion

            Console.ReadLine();

        }

 

二、sealed class 

在 C# 中,sealed class密封类,它的作用是防止该类被继承

sealed 关键字的作用

  • 防止类被继承sealed class)。
  • 防止方法被子类重写sealed override)。   
  • sealed class sealedClassTest
    {
        public void ShowMessage()
        {
            Console.WriteLine("This is a sealed class.");
        }
    }
    class SubClass : sealedClassTest { }  // 报错:'sealedClassTest' 不能被继承

 sealed override(防止方法被重写)


    class BaseClass
    {
        public virtual void VirtualMethod()
        {
            Console.WriteLine("BaseClass Method");
        }
    }

    class DerivedClass : BaseClass
    {
        /// <summary>
        ///  sealed 这个方法加了sealed 来修饰,就不能被重写
        /// </summary>
        public sealed override void VirtualMethod()
        {
            Console.WriteLine("DerivedClass Method");
        }
    }
class SubDerivedClass : DerivedClass
{
        public  override void VirtualMethod() { } // 报错:不能重写被 sealed 关键字修饰的方法
 }

sealed class 的应用场景

✅ 何时使用 sealed

  1. 安全性:防止类被继承,确保核心逻辑不会被篡改。
  2. 优化性能:密封类比可继承类的调用更快(编译器可进行优化)。
  3. 特定用途的类:如 System.StringSystem.Math 这些类本身就是 sealed,不允许继承

序列化 sealed 类

sealed 类 ISerializable 自定义序列化

[Serializable]
sealed class Person : ISerializable
{
    public string Name { get; set; }
    public int Age { get; set; }

    public Person() { }

    // 序列化构造函数(反序列化时调用)
    private Person(SerializationInfo info, StreamingContext context)
    {
        Name = info.GetString("Name");
        Age = info.GetInt32("Age");
    }

    // 自定义序列化逻辑
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("Name", Name);
        info.AddValue("Age", Age);
    }
}
public static class Program
{
    static void Main()
    {
        Person person = new Person { Name = "Alice", Age = 30 };

        // 二进制序列化
        IFormatter formatter = new BinaryFormatter();
        using (Stream stream = new FileStream("person.bin", FileMode.Create, FileAccess.Write))
        {
            formatter.Serialize(stream, person);
        }

        Console.WriteLine("对象已序列化!");

        Console.ReadLine();

    }
  }

三、序列化static  

在 C# 中,static 变量默认不能被序列化,因为它属于类本身,而不是对象的实例
但如果你确实需要序列化 static 变量,可以使用以下几种方法:

手动序列化 static 变量(不推荐)

  [Serializable]
  class Hero
  {
      public string Name { get; set; }
      public int Age { get; set; }

      public static string staticVar = "this is  a string  var";

      public Hero() { }

      // 序列化的时候使用
      public void GetObjectData(SerializationInfo info, StreamingContext context)
      {
          info.AddValue("Name", Name);
          info.AddValue("Age", Age);

          // 手动存储静态变量
          info.AddValue("staticVar", staticVar);
      }

      // 反序列化时调用
      private Hero(SerializationInfo info, StreamingContext context)
      {
          Name = info.GetString("Name");
          Age = info.GetInt32("Age");

          // 手动恢复静态变量(⚠️ 仅适用于全局单例的场景)
          staticVar = info.GetString("staticVar");
      }
  }


  public static class Program
  {
      static void Main()
      {
          // 设置静态变量
          Hero.staticVar = "staticvar in  main";
          Hero  hero = new Hero();
          hero.Name = "Albert";
          hero.Age = 27;


          // 开始序列化
          IFormatter formatter = new BinaryFormatter();   // 二进制序列化
          using (Stream stream=new FileStream("hero.bin",FileMode.Create,FileAccess.Write))
          {
              formatter.Serialize(stream,hero);
          }

          // 修改静态变量,验证反序列化是否恢复
          Hero.staticVar = "abcedfghig";


          // 开始反序列化
          using (Stream stream = new FileStream("hero.bin", FileMode.Open, FileAccess.Read))
          {
              hero = (Hero)formatter.Deserialize(stream);
          }
          Console.WriteLine($"StaticData after deserialization: {Hero.staticVar}"); // "Static Data Before Serialization"
      
         Console.ReadLine();

      }


  }

使用 JsonSerializer 手动处理 static 变量(推荐)

 class Person
 {
     public string Name { get; set; }
     public int Age { get; set; }

     public static string StaticData = "This is static";

     // 手动添加静态变量
     public string StaticDataSerialized => StaticData;
 }


 public static class Program
 {

     static void Main()
     {

         Person person = new Person { Name = "Alice", Age = 30 };

         // 🔹 序列化
         string json = JsonSerializer.Serialize(person);
         Console.WriteLine(json);


         Console.ReadLine();

     }
}

 

 

 序列化 static 变量到单独的文件(强烈推荐)


    static class GlobalConfig
    {
        public static string Setting = "Dark Mode";

        public static void SaveConfig()
        {
            File.WriteAllText("config.json", JsonSerializer.Serialize(Setting));
        }

        public static void LoadConfig()
        {
            if (File.Exists("config.json"))
            {
                Setting = JsonSerializer.Deserialize<string>(File.ReadAllText("config.json"));
            }
        }
    }

 // 保存
 GlobalConfig.SaveConfig();

 // 修改静态变量
 GlobalConfig.Setting = "Light Mode";

 // 重新加载(恢复之前的值)
 GlobalConfig.LoadConfig();





 Console.WriteLine(GlobalConfig.Setting); // 输出:"Dark Mode

相关文章:

  • 【网络安全.渗透测试】Cobalt strike(CS)工具使用说明
  • 【状态空间方程】对于状态空间方程矩阵D≠0时的状态反馈与滑模控制
  • 细说STM32F407单片机RTC入侵检测和时间戳的原理及使用方法
  • 当没有OpenGL时,Skia如何绘制?
  • qt的QMainWindow保存窗口和恢复窗口状态
  • 《Stable Diffusion绘画完全指南:从入门到精通的Prompt设计艺术》 第一章
  • HCIA-路由器相关知识和面试问题
  • 《Performance Analysisi and Tuning on Modern CPU》阅读笔记
  • deepin linux UOS AI 使用 deepseek-r1 30B
  • git如何把多个commit合成一个
  • Jenkins 部署 之 Mac 一
  • 1 推荐系统概述
  • 【数据结构】(8) 二叉树
  • ES 索引结构
  • 优选驾考小程序
  • 如何优化数据库Update锁竞争
  • 直接调字典控制器传字典名称和字典Value查具体的字典Label
  • 【算法】动态规划专题⑫ —— 环形区间DP python
  • Flutter Gradle 命令式插件正式移除,你迁移旧版 Gradle 配置了吗?
  • 轻松打造专属音乐库:Alger Music本地部署与远程访问全流程解析
  • 哪条线路客流最大?哪个站点早高峰人最多?上海地铁一季度客流报告出炉
  • 气急败坏!20多名台湾艺人被台当局列为“重点核查对象”
  • 女生“生理期请病假要脱裤子证明”?高校回应:视频经处理后有失真等问题
  • 俄乌直接谈判结束,乌称“毫无成果”
  • 国寿资产获批参与第三批保险资金长期投资改革试点
  • 新华时评:让医德医风建设为健康中国护航