【CSharp高级编程】default和typeof运算符
前言
这部分本来应该和泛型一起讨论,考虑到分类问题,遂单独拿出来记录。
default运算符
早在C# 1
时代,typeof()
运算符就已经出现了,它接收一个类型名称作为唯一操作数。C# 2
加入了default()
运算符,并且略微拓展了typeof()
的用途。
default
运算符功能比较简单,它是一元运算符,其操作数是类型名或者类型形参,返回值是该类型的默认值。当声明一个字段,但是没有为该字段立刻赋值时,该字段的值就是默认值。如果是引用类型,默认值是一个null
引用。如果是非可空值类型,将返回对应类型的”0值”(0,0.0,0.0m,false,UTF-16编码单元的0等);如果是可空值类型则返回类型的null
值。
default
运算符可以用于类型形参以及提供了类型实参的泛型类型,例如如下都是合法的:
1 | default(T) |
default
运算符返回值的类型与操作数类型一致。**default
常与泛型类型形参一起使用**,因为对于非泛型类型可以通过其他方式获取default
值。但是对于泛型类型来说,我们不确定该泛型的初始值是什么类型的,这个时候就需要使用default
运算符了,代码示例:
1 | public T Last<T> (IEnumerable<T> source){ |
typeof运算符
typeof
运算符的使用相对复杂一些,考虑到如下几种常见的情形:
- 不涉及泛型,例如:
typeof(string)
- 涉及泛型但是不涉及类型形参,例如:
typeof(List<int>)
- 仅涉及类型形参,例如:
typeof(T)
typeof
操作数中有泛型,而且泛型作为类型形参出现,例如:typeof(List<TItem>)
- 涉及泛型,但是操作数中没有出现类型实参,例如:
typeof(List<>)
其中第一个场景最简单,且其用法基本没有变过。对于其他的场景需要进行考虑。typeof
运算符的返回值是Type
类型的值,而且Type
类在经过拓展之后可以支持泛型。
要理解typeof
运算符,一个简单的例子是**typeof(List<int>)
,其返回值是List<int>
的Type
值,结果与调用new List<int>().GetType()
相同**。
现在来讨论typeof(T)
,该表达式返回的是调用代码中T
类型参数的Type
。它的返回值永远是一个封闭的,已构造的类型,技术规范中将其描述为一个真正不包含任何类型形参的类型。
下面通过一个实例来展示typeof(T)
和typeof(List<T>)
,代码示例:
1 | //程序入口 |
运行结果:
结果一幕了然,其中还展示了使用反射时泛型类型的命名格式:List '1(注是斜上点,Markdown字符冲突)'
,表示这是一个命名为List
的泛型类型,其度为 1 ,后面的方括号表示类型实参。
最后再说明一下typeof(List<>)
。该表达式看起来缺少类型实参。这种写法只有在typeof
运算符中才有效,且指向了泛型类型定义。对于度为 1 的泛型,其书写格式为TypeName<>
,**如果其度大于1,每增加一个度,就加一个逗号,例如要获取D<T1,T2>
泛型类型定义,则表达式为: Typeof(TypeName<,>)
**。
End
说实话,这两种运算符,在实际应用过程并没有那么的应用,是一种数据获取手段,此处单独摘录说明,看看我接下来有没有时间写一下C#
多线程的内容。
就这样,祝晚安。