[C#2] 4-可空类型、静态类

简介: 1. 可空类型 值类型是不可以为null的[即不可为空值], 假如我们想让它为null呢[比如它对映这数据库中的某个表的某个字段,但是这个字段是null]。 自己实现的话,简单的写一个类,有一个值类型的字段,检查该字段是否初始化,是的话返回该值,否的话返回null。

1. 可空类型

值类型是不可以为null的[即不可为空值], 假如我们想让它为null呢[比如它对映这数据库中的某个表的某个字段,但是这个字段是null]。 自己实现的话,简单的写一个类,有一个值类型的字段,检查该字段是否初始化,是的话返回该值,否的话返回null。 假如是在C#1.0时,那么每个值类型都要写这么一份代码了。C#2.0有了泛型的支持,所以我们可以定义一个泛型版的。 幸运的是C#2.0带来了一个新的类型[System.Nullable<T>]帮我们实现了,T就是需要传入的类型[约束为值类型]. 比如:

Nullable<int> i=null;   
//简写?
int? i=null;

下面是System.Nullable<T>泛型类原型:

 1 [Serializable]//表示了序列化
 2 public struct Nullable<T> where T : struct
 3 {
 4     //构造器,初始化类型参数T
 5     public Nullable(T value);
 6     //重载类型转换操作符<显示转换:int i=(int)Nullable<int>类型变量>
 7     public static explicit operator T(T? value);
 8     //重载类型转换操作符<隐式转换:int? i=int类型变量>
 9     public static implicit operator T?(T value);
10     //判断是否是null,
11     public bool HasValue { get; }
12     //如果不是null,取得值
13     public T Value { get; }
14     //重写Equals
15     public override bool Equals(object other);
16     //重写GetHashCode
17     public override int GetHashCode();
18     //如果HasValue属性为true,返回Value属性的值
19     //否则返回当前 Nullable<T> 对象<类型是T>的默认值
20     //即使 HasValue属性为false,GetValueOrDefault方法也会返回一个值
21     //(这与 Value 属性不同,该属性将引发异常)。
22     public T GetValueOrDefault();
23     //同上,参数是指定的默认值,如果int? i=null;
24     //int j=i.GetValueOrDefault(10);则j的值为10
25     public T GetValueOrDefault(T defaultValue);
26     //重写ToString
27     public override string ToString();
28 }

各个方法使用DEMO:

static void Main()
{
    Nullable<int> i = null;
    int l = i.GetValueOrDefault();//l=0
    int n = i.GetValueOrDefault(10);//j=10
    int h = i.HasValue ? i.Value : default(int);//h=0
    int m = 100;
    i = m;//隐式转换
    m = (int)i;//显示转换  
    Console.WriteLine(i.Equals(m));//true
    Console.WriteLine(i.GetType());//System.Int32
    Console.WriteLine(i.ToString());//100
}

现在做些运算:

static void Main()
{
    Nullable<int> i = 1;
    int? j = 2;
    //执行运算之前会先调用HasValue属性
    int l = (int)(i + j);
    Console.WriteLine(l);//3
    i = null;
    //抛出异常System.InvalidOperationException
    //其中一个为null则结果就为null,所以null无法转换为int
    int n = (int)(i + j);  
    Console.WriteLine(n);
}

它的这些运算还是蛮繁琐的,先检查是否为null,如果都不是null,再取得各自的值在运算,否则返回null。 不是迫不得已的情况下最好不使用[效率不怎么好]。

2. 静态类

静态类是只用于包含静态成员,它既不能实例化,也不能被继承。 它相当于一个sealed abstract类[查看IL代码实际上静态类就是被标识为sealed和abstract]。 相当于提供一些功能性的全局函数[C#不支持全局函数,但是CLR支持,IL支持,这算是一种变相的实现全局函数吧]。

静态类不能有实例构造器;

静态类不能有任何实例成员;

静态类上不能使用abstract或sealed修饰符;

静态类默认继承自System.Object根类,不能显式指定任何其他基类[实际上也没有什么意义的];

静态类不能指定任何接口实现。;

静态类的成员不能有protected 或 protected internal访问保护修饰符[这些都是供子类访问的,但是静态类不允许被继承,所以你用这些访问修饰符没有任何意义]。

作者: Blackheart
目录
相关文章
|
8月前
|
存储 安全 编译器
C# 11.0中的泛型属性:类型安全的新篇章
【1月更文挑战第23天】C# 11.0引入了泛型属性的概念,这一新特性为开发者提供了更高级别的类型安全性和灵活性。本文将详细探讨C# 11.0中泛型属性的工作原理、使用场景以及它们对现有编程模式的改进。通过深入了解泛型属性,开发者将能够编写更加健壮、可维护的代码,并充分利用C#语言的最新发展。
|
5天前
|
JSON C# 数据格式
【Azure Function】C#独立工作模式下参数类型 ServiceBusReceivedMessage 无法正常工作
Cannot convert input parameter 'message' to type 'Azure.Messaging.ServiceBus.ServiceBusReceivedMessage' from type 'System.String'.
97 73
|
2月前
|
编译器 C#
c# - 运算符<<不能应用于long和long类型的操作数
在C#中,左移运算符的第二个操作数必须是 `int`类型,因此需要将 `long`类型的位移计数显式转换为 `int`类型。这种转换需要注意数据丢失和负值处理的问题。通过本文的详细说明和示例代码,相信可以帮助你在实际开发中正确使用左移运算符。
45 3
|
2月前
|
编译器 C#
c# - 运算符<<不能应用于long和long类型的操作数
在C#中,左移运算符的第二个操作数必须是 `int`类型,因此需要将 `long`类型的位移计数显式转换为 `int`类型。这种转换需要注意数据丢失和负值处理的问题。通过本文的详细说明和示例代码,相信可以帮助你在实际开发中正确使用左移运算符。
75 1
|
3月前
|
C#
C# 可空类型(Nullable)
C# 单问号 ? 与 双问号 ??
65 12
|
2月前
|
编译器 C#
c# - 运算符<<不能应用于long和long类型的操作数
在C#中,左移运算符的第二个操作数必须是 `int`类型,因此需要将 `long`类型的位移计数显式转换为 `int`类型。这种转换需要注意数据丢失和负值处理的问题。通过本文的详细说明和示例代码,相信可以帮助你在实际开发中正确使用左移运算符。
27 0
|
4月前
|
存储 C# 开发者
C#一分钟浅谈:静态成员与静态类介绍
在C#编程中,`static`关键字用于创建静态字段、方法、属性和构造函数等,这些成员属于类本身而非实例。本文从基本概念入手,详细探讨了静态成员与静态类的特点、应用场景及常见误区。通过示例代码展示了如何使用静态字段和方法,并讨论了静态类的定义及其在工具箱和常量集合中的应用。最后总结了正确使用这些特性的策略,以帮助开发者编写高效、可维护的代码。
93 11
|
5月前
|
存储 C#
揭秘C#.Net编程秘宝:结构体类型Struct,让你的数据结构秒变高效战斗机,编程界的新星就是你!
【8月更文挑战第4天】在C#编程中,结构体(`struct`)是一种整合多种数据类型的复合数据类型。与类不同,结构体是值类型,意味着数据被直接复制而非引用。这使其适合表示小型、固定的数据结构如点坐标。结构体默认私有成员且不可变,除非明确指定。通过`struct`关键字定义,可以包含字段、构造函数及方法。例如,定义一个表示二维点的结构体,并实现计算距离原点的方法。使用时如同普通类型,可通过实例化并调用其成员。设计时推荐保持结构体不可变以避免副作用,并注意装箱拆箱可能导致的性能影响。掌握结构体有助于构建高效的应用程序。
160 7
|
5月前
|
程序员 C#
C# 语言类型全解
C# 语言类型全解
36 0
|
5月前
|
开发框架 .NET 编译器
C# 中的记录(record)类型和类(class)类型对比总结
C# 中的记录(record)类型和类(class)类型对比总结