C#和VB.NET中有一些和类型相关的方法和关键字,初学者刚开始理解可能会有点混乱,这里整理一下,希望对初学者有所帮助。如果大家有需要补充的内容,欢迎回复。
1.GetType
(1)Object.GetType()
该方法是所有对象都有的方法,MSDN中的解释是“获取当前实例的 Type。”。该方法的返回值是System.Type类型的实例,表示当前实例的确切运行时类型。
例如:
C#:
System.Type t = number.GetType();
Console.WriteLine(t.FullName); // 输出:System.Int32
VB.NET:
Dim t As System.Type = number.GetType()
Console.WriteLine(t.FullName) ' 输出:System.Int32
(2)VB.NET中的GetType方法
参考MSDN中的解释:返回指定类型的 Type 对象。Type 对象提供有关类型的信息,如类型的属性、方法和事件。
用法:GetType(typename),其中typename是需要获取其信息的类型的名称。
例如:
Console.WriteLine(t.FullName) ' 输出:System.Int32
(3)Type.GetType系列方法
System.Type类型中的GetType方法一共有4个,其中不带参数的GetType()是继承自Object的实例方法,其他三个是静态方法(C#中为static,VB.NET中为Shared)。实例方法不用介绍了,就是Object.GetType()。静态方法是通过类型名称的字符串获取System.Type。MSDN中的解释有一大篇,这里只给出简单示例:
C#:
Console.WriteLine(t.FullName); // 输出:System.Int32
VB.NET
Console.WriteLine(t.FullName) ' 输出:System.Int32
注意这里的类型名称必须是包含命名空间的全名,即System.Type的FullName,不能是C#或者VB.NET中的类型名称,如C#中的"int"或者VB.NET中的"Integer"
2.typeof
在C#和VB.NET中都有typeof关键字,但它们的用法却不一样。
C#中typeof相当于VB.NET中的GetType,用于获取指定类型的 Type 对象。
用法
Console.WriteLine(t.FullName); // 输出:System.Int32
VB.NET中的TypeOf则总是与Is关键字一起用于构造TypeOf…Is表达式。MSDN中对该关键字的解释是:比较对象引用变量与数据类型。需要注意的是该表达式只能针对引用类型,如果把下面的示例中的i声明为Integer则会出错。
VB.NET用法:
Console.WriteLine( TypeOf i Is Integer ) ' 输出:True
Console.WriteLine( Typeof i Is Double ) ' 输出:False
3.is
在C#和VB.NET中也都存在is关键字,当然它们的用法也不一样。
C#中is 的作用是:检查对象是否与给定类型兼容。它执行的是类型比较。MSDN中的备注:如果所提供的表达式非空,并且所提供的对象可以强制转换为所提供的类型而不会导致引发异常,则 is 表达式的计算结果将是 true。请注意,is 运算符只考虑引用转换、装箱转换和取消装箱转换。不考虑其他转换,如用户定义的转换。
可以认为C#中的is 相当于VB.NET中的TypeOf…Is。
用法:
Console.WriteLine(i is int ); // 输出:True
Console.WriteLine(i is double ); // 输出:False
VB.NET中Is 的作用是:比较两个对象引用变量。MSDN中的备注:Is 运算符确定两个对象引用是否引用同一个对象。但是,它不执行值比较。如果 object1 和 object2 引用同一个对象实例,则 result 为 True;如果它们不引用同一个对象,则 result 为 False。该运算符和TypeOf…Is一样,也只适用于引用类型。
用法:
Dim j AS String = " Hello "
Dim k as String = " Hello world "
Console.WriteLine(i Is j) ' 输出:True
Console.WriteLine(i Is k) ' 输出:False
k = j
Console.WriteLine(i Is k) ' 输出:True
4.as
同样C#和VB.NET里面都存在as,用法也不一样。
C#中as 的作用是:as 运算符用于在兼容的引用类型之间执行转换。as 运算符类似于强制转换操作。但是,如果无法进行转换,则 as 返回 null 而非引发异常。
expression as type 等效于 expression is type ? (type)expression : (type)null
用法:
If(s != null )
Console.WriteLine( " someObject is a string " );
VB.NET中As 的作用是:引入 As 子句,该子句标识声明语句中的数据类型或泛型类型参数中的约束列表。
在VB.NET中这个关键字太常见了,就不需要过多解释。
用法:
Dim j As String = " hello " ' 声明变量
Sub Test( ByVal k As Boolean ) ' 声明参数
Public Class MyClass ( Of T As {IComparable, IDisposable, Class , New }) ' 泛型类型约束
5.类型转换
类型转换是在编程过程中经常会遇到的。在这两种语言中,有共同的方法,也有各自特有的方法。
共同的方法是Convert类的使用,因为Convert类是System命名空间中的。该类中包含了各种常见类型的转换方法,比如ToInt32, ToSingle, ToBoolean等,这些方法的返回值就是需要的类型,不需要经过转换。Convert类中通用的类型转换方法是ChangeType,该方法返回具有指定类型而且其值等效于指定对象的Object,这时候就需要对返回值进行显示转换了。
C#:
int i = ( int )Convert.ChangeType(d, typeof ( int ));
VB.NET:
Dim i As Integer = CInt (Convert.ChangeType(d, GetType ( Integer )))
关于显式转换
C#中的显式转换的格式是(type)expression
用法:
int i = ( int )d;
VB.NET中显式转换的格式是CType(expression,type)。MSDN中关于CType的解释:CType 是一个“内联函数”,这意味着转换是由已编译的代码执行的,通常不会生成函数调用。这将提高性能。
用法:
Dim i As Integer = CType (d, Integer )
VB.NET中还有一系列函数与CType函数同属于Conversion函数,例如CBool, CInt, CString, Hex, Format, Val等等,这些函数都是内联函数,具体的用法可以参考MSDN。
另外在VB.NET中还包含两个特殊的转换方法,DirectCast和TryCast。这两个方法和CType的用法一样,它们的区别见下表。
关键字 | 数据类型 | 参数关系 |
CType | 任何数据类型 | 必须在两种数据类型之间定义扩大转换或收缩转换 |
DirectCast | 任何数据类型 | 一个类型必须继承或者实现另一个类型 |
TryCast | 仅引用类型 | 一个类型必须继承或者实现另一个类型 |
从上表可以看出,VB.NET的TryCast和C#的as作用是一样的。
DirectCast示例(摘自MSDN):
Dim i As Integer = CType (q, Integer )
' The following conversion fails at run time
Dim j As Integer = DirectCast (q, Integer )
Dim f As New System.Windows.Forms.Form
Dim c As System.Windows.Forms.Control
' The following conversion succeeds.
c = DirectCast (f, System.Windows.Forms.Control)
TryCast示例(摘自MSDN):
Dim objAsConvertible As IConvertible = TryCast(obj, IConvertible)
If objAsConvertible Is Nothing Then
Return obj.ToString() & " does not implement IConvertible "
Else
Return " Type code is " & objAsConvertible.GetTypeCode()
End If
End Function
6.Parse相关方法
在很多类型中还存在着一种针对字符串的类型转换方法,即Parse和TryParse。这两个方法都是静态方法,接受的参数为字符串,将指定类型的字符串表示形式转换为该类型的等效值。不同的是Parse转换失败则抛出错误,而TryParse则可以通过返回的逻辑值值了解转换是否成功。这两个方法的用法如下:
C#:
int j = int .Parse( " 123.4 " ); // 抛出错误
int k = 0 ;
// 下面输出:False_0
Console.WriteLine( int .TryParse( " 456.7 " , out k).ToString() + " _ " + k.ToString());
// 下面输出:True_789
Console.WriteLine( int .TryParse( " 789 " , out k).ToString() + " _ " + k.ToString());
VB.NET:
Dim j As Integer = Integer .Parse( " 123.4 " ) ' 抛出错误
Dim k As Integer = 0
' 下面输出:False_0
Console.WriteLine( Integer .TryParse( " 456.7 " , k).ToString() & " _ " & k.ToString())
' 下面输出:True_789
Console.WriteLine( Integer .TryParse( " 789 " , k).ToString() & " _ " & k.ToString())
7.空值的比较
空值在C#中为null,在VB.NET中为Nothing。虽然这两个关键字看起来似乎一样,但它们有所不同。
C#中的解释:null 是引用类型变量的默认值。在C#中判断变量是否是空值,通过expression == null或者expression != null即可,即使expression是值类型也不会抛出错误,不过会有警告信息。例如下面的代码:编译时会提示如下警告信息:由于“int”类型的值永不等于“int?”类型的“null”,该表达式的结果始终为“false”。
Console.WriteLine(i == null ); // 输出:False
i = null ; // 错误
VB.NET中的解释:Nothing表示任意数据类型的默认值。将 Nothing 赋给变量将把该变量设置为其声明类型的默认值。如果该类型包含变量成员,则这些成员都会设置为其默认值。这里的解释和C#不一样,可以是任何数据类型,下面的代码中会给出验证。VB.NET中判断变量是否为空值,可以用expression = Nothing,expression <> Nothing, expression Is Nothing,expression IsNot Nothing等来判断。一般值类型用前面两种,引用类型用后面两种。编写如下代码测试:
Console.WriteLine(i = Nothing ) ' 输出:True。可以看出Nothing在此表示0,是Integer的默认值。
i = 1
Console.WriteLine(i = Nothing ) ' 输出:False
i = Nothing
Console.WriteLine(i = Nothing ) ' 输出:True
Console.WriteLine(i) ' 输出:0。再次验证Nothing和0等价。
' Console.WriteLine(i Is Nothing) '报错,Is的操作数必须是引用类型或可为null的类型。
Dim s As String
Console.WriteLine(s & " abc " ) ' 输出:abc
Console.WriteLine( String .IsNullOrEmpty(s)) ' 输出:True
Console.WriteLine(s = Nothing ) ' 输出:True
Console.WriteLine(s Is Nothing ) ' 输出:True。
s = ""
Console.WriteLine( String .IsNullOrEmpty(s)) ' 输出:True
Console.WriteLine(s = Nothing ) ' 输出:True。Nothing表示String的默认值""。
Console.WriteLine(s Is Nothing ) ' 输出:False。
s = Nothing
Console.WriteLine( String .IsNullOrEmpty(s)) ' 输出:True
Console.WriteLine(s = Nothing ) ' 输出:True
Console.WriteLine(s Is Nothing ) ' 输出:True
Dim c As SomeClass
' 没有为类型"SomeClass"和"SomeClass"定义运算符"="
' Console.WriteLine(c = Nothing)
Console.WriteLine(c is Nothing ) ' 输出:True
c = New SomeClass()
Console.WriteLine(c is Nothing ) ' 输出:False
以上代码可以看出VB.NET中对Nothing的处理的特殊之处。通过SharpDevelop转换这些VB.NET代码成C#代码,把所有Nothing都转换成null了,VB.NET中的"="和"Is"都转换成"==",很显然代码无法通过编译。通过Reflector用C#模式查看代码,"="和"Is"也都转换成"==",但"i = Nothing"都转换成"i == 0",这才是正确的代码。可以看出VB.NET的编译器在背后做了一些转换的工作。
既然VB.NET能够把Nothing解释为默认值,C#里有没有一个获取默认值的功能呢?当然有,那就是default。用法是default(typename),比如Console.WriteLine(default(int));这句代码输出0。通过Reflector查看,这句代码被转换成了Console.WriteLine(0);又是编译器在背后做了工作。
8.可空类型
首先看一下可空类型的说明:表示基础类型为值类型的对象,值类型与引用类型一样也可以分配 null 引用(在 Visual Basic 中为 Nothing)。
某些值类型并不总是具有(或需要)已定义的值。在可能没有为某些字段赋予任何值的数据库中,这是常见的实际情况。例如,您可以将 null 值赋予数据库字段以表示尚未给该数据库字段赋值。通过可空类型,可以向一个类型的默认值范围中再添加一个为空的值。
可空类型在系统中有一个专门的类型,Nullable,一般使用泛型可空类型,C#为Nullable<T>,VB.NET为Nullable(Of T)。除了采用类名称来定义外,在这两种语言中都有简写形式的定义,下面代码中的定义是等价的:
C#:
int ? j = null ;
VB.NET:
Dim j? As Integer = Nothing ' VS2005不支持这种写法
定义为可空类型的变量,可以和原始类型的变量一起进行运算,比如i+j,但是需要判断该变量是否有值,否则可能出错。判断可空类型的变量是否有值,可以通过HasValue属性来判断,然后通过Value属性来获取值。可空类型还有一个方法,GetValueOrDefault,如果有值,则获取Value,如果为空,则获取基础类型的默认值。详细用法请参考MSDN。
另外在C#中还有一个特殊的运算符??,该运算符的用法为j = i ?? 5;意思是如果i不为空,则返回i的值,否则返回5。查看MSDN中的解释:如果 ?? 运算符的左操作数非 null,该运算符将返回左操作数,否则返回右操作数。通过该运算符可以简化判断取值的方法。
9.空数据类型
在系统还存在一种特殊的类型,DBNull。在操作数据库的时候,获取的数据项没有值,这个数据项可能不是null(Nothing),而是DBNull。下面验证这两个值的不同:
C#:
VB.NET:
在使用DBNull的时候必须使用DBNull.Value,如下:
C#:
Console.WriteLine(item != DBNull.Value);
VB.NET:
Console.WriteLine(item = DBNull.Value)
本文就写到这里了,希望对初学者有所帮助。因为代码比较简单,其中的变量使用了简单的字母命名。文中有什么不足之处,还请大家指正。