C#中变量、常量、枚举、预处理器指令知多少

一、变量

C#共有其中变量类型有:静态变量、实类变量、数组元素、数值参数、引用参数、输出参数和局部变量

先定义一个简单的类来说明,如下:

public class VariableDefine
  {
    private static uint variableUInt;
    public static uint VariableUInt { get => variableUInt; set => variableUInt = value; }
    string VariableStr;
    public VariableDefine(string version)
    {
      VariableStr = version;
    }

    public static void Fun()
    {
      Console.WriteLine(variableUInt);
    }

    /// <summary>
    /// 变量类型
    /// </summary>
    /// <param name="intArray">intArray[0]数组元素</param>
    /// <param name="a">数值参数</param>
    /// <param name="b">引用类型</param>
    /// <param name="c">输出参数</param>
    public void Fun(int[] intArray, int a, ref int b, out int c)
    {
      //局部变量i
      var i = 0;
      c = i;
    }
  }

对于静态变量在被创建加载之后失效,当被卸载后失效,静态变量的初始值也为此类型的变量的默认值

对于实例变量当创建某类的一个实例的时候,隶属于该类的实例变量也被生成,当不再有关于这个实例的引用而且实例的析构函数执行了以后,此实例变量失效

对于数组元素当任意一个数组实例被创建时,这个数组的元素也被同时创建,当不再有任何正对这个数组实例的引用时,它的元素也就此失效

当一个不带有ref 或out 修饰参数被声明时,我们称它为数值参数

参数当一个带有ref 修饰语的参数被声明时,我们称之为引用参数

参数当一个带有out 修饰语的参数被声明时,我们称之为输出参数

局部变量被局部变量声明语句创建

C#编译器不容许在表达式中使用未初始化的变量

变量初始化要注意两点的是:(1)变量是类或结构中的字段,如果没有显示初始化,创建这些变量时,其默认值就是0(2)方法的局部变量必须在代码中显示初始化,之后才能在语句中使用它们的值。

二、常量

C#可以定义两种类型的常量,静态常量用const来定义在程序编译的时候确定,一种是动态常量用readonly来定义在运行时确定

静态常量使用方便,性能高,但一旦定义之后就不可以改变,在一个引用第三方程序集上面如果定义了一个静态常量,当它定义的值改变时你不得不重新引用生成主程序

动态常量使用灵活,能很好的支持程序的扩展性

下面一个事例就是通过读取XML文档来给动态常量赋值

public sealed class ReadOnlyModel
  {
    public readonly List<Company> ListCompany;
    public ReadOnlyModel(string companyInfoPath)
    {
      XElement companys = XElement.Load(companyInfoPath);
      var elements = from e in companys.Elements("company")
              where e.Element("name").Value.Equals("C#")
              select e;
      ListCompany = GetListCompany(elements);
    }

    /// <summary>
    /// 解析xml文档
    /// </summary>
    /// <param name="elements"></param>
    /// <returns></returns>
    private List<Company> GetListCompany(IEnumerable<XElement>elements)
    {
      var listCompany = new List<Company>();
      foreach (var element in elements)
      {
        var companyModel = new Company()
        {
          CompanyName = element.Element("name").Value,
          CompanyEmail = element.Element("email").Value
        };
        listCompany.Add(companyModel);
      }
      return listCompany;
    }
  }

根据传入的路径来解析XML文件赋值给动态常量,能很好的扩展应用程序的常量值

三、枚举

枚举是用户定义的整数类型,在声明一个枚举时,要指定该枚举的实例可以包含的一组可以接受的值,枚举具有如下的优势:

1.枚举可以使代码更易于维护,有助于确定给变量指定合法的,期望的值

2.枚举使代码更清晰,允许用描述性的名称来表示整数,而不是含义模糊、变化多端的数

3.枚举也是代码更易于输入

在实际应用中通常在枚举上面加上Description需要显示的枚举特性值,在页面显示的时候通常显示的也是枚举的特性值,所以有必要写一个获取枚举特性值的通用方法

class Program
  {
    static void Main(string[] args)
    {
      //ReadOnlyModel readOnlyCompany = new ReadOnlyModel(@"D:\GitHubProject\C#AdvancedProgramming\VariableDefine\VariableDefine\bin\Debug\Test-Parking-SN.xml"); //C:\Program Files(x86)\FPOnline
      //foreach (var company in readOnlyCompany.ListCompany)
      //{
      //  Console.WriteLine("company name is {0} company email is {1}", company.CompanyName, company.CompanyEmail);
      //}
      //Console.WriteLine("company name is {0} company email is {1}", ConstClass.CompanyName, ConstClass.CompanyEmail);
      MemberLevel superMember = MemberLevel.SuperMember;
      Console.WriteLine(superMember.GetDescriptionEnum());
      Console.ReadKey();
    }
  }

  public enum MemberLevel
  {
    [Description("超级会员")]
    SuperMember=1,
    [Description("一般会员")]
    Member=2,
    [Description("普通用户")]
    GeneralUser=3
  }

  public static class EnumExtension
  {
    public static string GetDescriptionEnum(this Enum enumValue)
    {
      DescriptionAttribute attr = null;
      var enumType = enumValue.GetType();
      string name = Enum.GetName(enumType, enumValue);
      if (name != null)
      {
        FieldInfo fieldInfo = enumType.GetField(name);
        if (fieldInfo != null)
          attr = Attribute.GetCustomAttribute(fieldInfo, typeof(DescriptionAttribute), false) as DescriptionAttribute;
      }
      if (attr != null && !string.IsNullOrEmpty(attr.Description))
        return attr.Description;
      else return string.Empty;
    }
  }

参考博客:枚举知多少

四、C#的预处理指令

使用预处理指令可以禁止编译器编译与额外功能相关的代码,以控制不同版本拥有的功能,如企业版和基本版本

#define(给定名称的符号)和#undef(删除名称的符号)一般与#if、#elif、#else、#endif结合起来使用如

没有找到预定义的Debug就不会执行 #if和#endif代码块里面的语句,这也称为条件编译。

同样的预处理器指令有:#warning和#error,当编译器遇到它们时,会分别产生警告或错误,如果编译器遇到#warning指令,会给用户显示#warning后面的文本,之后编译继续,如果编译器遇到#error指令,就会给用户显示后面的文本,作为一条编译错误消息,然后立即退出编译。

#region和#endregion指令用于把一段代码标记为有给定名称的一个块,#line指令用于改变编译器在警告和错误信息中显示的文件名和行号信息,#pragm可以印制或还原指定的编译警告参考:https://msdn.microsoft.com/zh-cn/library/yt3yck0x.aspx

(0)

相关推荐

  • C#中变量、常量、枚举、预处理器指令知多少

    一.变量 C#共有其中变量类型有:静态变量.实类变量.数组元素.数值参数.引用参数.输出参数和局部变量 先定义一个简单的类来说明,如下: public class VariableDefine { private static uint variableUInt; public static uint VariableUInt { get => variableUInt; set => variableUInt = value; } string VariableStr; public Var

  • C#中的预处理器指令详解

    目录 1. #define 和 #undef 2. #if.#elif.#else 和#endif 3. #warning 和 #error 4. #region 和#endregion 5. #line 6. #pragma C#中有许多名为"预处理器指令"的命令.这些命令从来不会转化为可执行代码中的命令,但会影响编译过程的各个方面. 例如,使用预处理器指令可以禁止编译器编译代码的某一部分.如果计划发布两个版本的代码,即基本版本和拥有更多功能的企业版本,就可以使用这些预处理器指令.在

  • C#预处理器指令的用法实例分析

    本文实例讲述了C#预处理器指令的用法.分享给大家供大家参考.具体用法分析如下: C#预处理器指令是在编译时调用的.预处理器指令(preprocessor directive)告诉C#编译器要编译哪些代码,并指出如何处理特定的错误和警告.C#预处理器指令还可以告诉C#编辑器有关代码组织的信息. 1. 定义符号和取消符号定义的预处理指令#define 和 #undef 预处理指令都以#号开头并位于行首前面可以出现空格符. 复制代码 代码如下: #define DEBUG #define ISSAY

  • 深入理解C预处理器

    C 预处理器不是编译器的组成部分,是编译过程中一个单独的步骤.C预处理器只是一个文本替换工具,它会指示编译器在实际编译之前完成所需的预处理. 所有的预处理器命令都是以井号(#)开头.它必须是第一个非空字符,为了增强可读性,预处理器指令应从第一列开始. 下表包含所有重要的预处理器指令: 指令 描述 #define 定义宏 #include 包含一个源代码文件 #undef 取消已定义的宏 #ifdef 如果宏已经定义,则返回真 #ifndef 如果宏没有定义,则返回真 #if 如果给定条件为真,则

  • C语言预处理器使用方法讲解

    目录 预处理器实例 预定义宏 预处理器运算符 参数化的宏 C 预处理器不是编译器的组成部分,但是它是编译过程中一个单独的步骤.简言之,C 预处理器只不过是一个文本替换工具而已,它们会指示编译器在实际编译之前完成所需的预处理.我们将把 C 预处理器(C Preprocessor)简写为 CPP. 所有的预处理器命令都是以井号(#)开头.它必须是第一个非空字符,为了增强可读性,预处理器指令应从第一列开始.下面列出了所有重要的预处理器指令: 预处理器实例 分析下面的实例来理解不同的指令. #defin

  • 简介C/C++预处理器的一些工作

    多么令人愉快的一个问题啊 就在被带到编译器那里之前,预处理器都会对你的源代码瞧上一瞧, 做一些格式化的工作,并执行任何你在源代码里面留给它来执行的指令. 像什么? 好吧,预处理器的指令就被叫做预处理器指令,而他们都以一个#开头. 像 #include 这样? 正确. 每一个被预处理器遇到的 # 命令都会导致在某种方式上对源代码的修改. 让我们来简单的研究研究它们,然后我们就会之后这背后都是怎么运转的了. #include 包含其他库.类.接口等的头文件.预处理器实际上就只是把整个头文件复制到你的

  • 浅谈c++ 预处理器

    预处理器是一些指令,指示编译器在实际编译之前所需完成的预处理. 所有的预处理器指令都是以井号(#)开头,只有空格字符可以出现在预处理指令之前.预处理指令不是 C++ 语句,所以它们不会以分号(;)结尾. 我们已经看到,之前所有的实例中都有 #include 指令.这个宏用于把头文件包含到源文件中. C++ 还支持很多预处理指令,比如 #include.#define.#if.#else.#line 等,让我们一起看看这些重要指令. #define 预处理 #define 预处理指令用于创建符号常

  • C/C++ 活动预处理器详解

    预处理器简介 预处理器不是编译器的组成部分,他是编一过程中的一步,发生在编译之前.我们把C预处理器(C Preprocessor)简称为CPP.预处理的作用就是在代码被编译前对代码做某些替换. 指令规则 预处理指令的写法都是以#开头,#必须是该行第一个非空白字符,#和关键字之间允许存在任意个数的空白字符,接着是指令所需要的其他信息,整行够成了一条预处理指令.预处理指令总是在第一个换行符结束,除非明确的指明指令要继续.预处理指令可以出现在文件的任何地方.通常我们将#define和#include指

  • 详解C语言编程中预处理器的用法

    预处理最大的标志便是大写,虽然这不是标准,但请你在使用的时候大写,为了自己,也为了后人. 预处理器在一般看来,用得最多的还是宏,这里总结一下预处理器的用法. #include <stdio.h> #define MACRO_OF_MINE #ifdef MACRO_OF_MINE #else #endif 上述五个预处理是最常看见的,第一个代表着包含一个头文件,可以理解为没有它很多功能都无法使用,例如C语言并没有把输入输入纳入标准当中,而是使用库函数来提供,所以只有包含了stdio.h这个头文

  • 详解Golang编程中的常量与变量

    Go语言常量 常量是指该程序可能无法在其执行期间改变的固定值.这些固定值也被称为文字. 常量可以是任何像一个整型常量,一个浮点常量,字符常量或字符串文字的基本数据类型.还有枚举常量. 常量是一样,只是它们的值不能自己定义后进行修改常规变量处理. 整型常量 一个整数文字可以是十进制,八进制,或十六进制常数.前缀指定基或基数:0x或0X的十六进制,0表示八进制,并没有为十进制. 一个整数文字也可以有一个后缀为U和L的组合,分别为无符号和长整型.后缀可以是大写或小写,并且可以以任意顺序. 这里是整数常

随机推荐