黑马程序员_分部类型和可空类型

------- Windows Phone 7手机开发.Net培训、期待与您交流! ------- 

 分部类型和可空类型

分部类型允许将一个类或结构或接口分成几个部分,由不同的人去编写,存放在不同的源文件中。在多人共同研发项目时,使用分部类型便于开发和维护代码,增加代码的灵活性。可空类型是用来处理值类型的值为空的情况,它能够指示可空类型的实例是否包含一个确定的值。

使用分部类型

分部类型(Partial type)允许将类、结构和接口划分为多个部分,并存储在不同的源文件中。如果把某个类设置为分部类,那么该类的代码可以保存在不同的源文件中,增加了代码的灵活性。

声明分部类

分部类跟普通的类一样,在使用之前必须声明。声明分部类需要使用partial修饰符。声明分部类型的每一个部分时都必须包含partial修饰符,并且该分部类型的所有声明代码都必须位于同一命名空间中。partial修饰符表示它所在的类型可能还包含其他部分,但是其他部分并不一定是必需的。如果一个类型只包含一个部分,在声明该类型时使用了partial修饰符,也是正确的。

如果一个分部类型的任何一个部分被声明为抽象的,则该类型都被视为抽象的。如果一个分部类型的任何一个部分被声明为密封的,则该类型都被视为密封的。如果一个分部类型的任何一个部分声明基类型,则该类型都将继承该基类。

注意:partial修饰符不能用于声明委托或枚举。

下面声明一个名称为Program的分部类的一部分。Program类的该部分代码包含一个名称为name的字段,它的类型为string。

public partial class Program            //声明分部类Program

{

    string name;

}

下面声明一个名称为Program的分部类的另外一部分。Program类的该部分代码包含一个名称为age的字段,它的类型为int。

public partial class Program            //声明分部类Program

{

    int age;

}

那么上述两个分部类构成的Program分部类等效于以下声明的Program类。

public class Program

{

    string name;

    int age;

}

注意:分部类型的所有部分必须一起编译,编译器最终将该类型的各个部分合成在一起,并构成一个整体来表示该类型。

声明分部结构

同分部类一样,可以使用partial修饰符声明分部结构。

下面声明名称为Str的分部结构的一部分。Str结构的该部分代码包含一个名称为X的字段,它的类型为int。

public partial struct Str                 //声明分部结构Str

{

    int X;

}

下面声明名称为Str的分部结构的另外一部分。Str结构的该部分代码包含一个名称为Y的字段,它的类型为int。

public partial struct Str

{

    int Y;

}

上面共同声明了Str结构。最终,Str结构包含了两个字段:X和Y。

声明分部接口

同分部类、分部结构一样,可以使用partial修饰符声明接口。

下面声明名称为Iinterface的分部接口的一部分。Iinterface接口的该部分代码包含一个名称为Name的属性,它的类型为int,并且该属性包含get和set访问器。

public partial interface Iinterface                 //声明分部接口Iinterface

{

    int Name

    {

        get;

        set;

    }

}

下面声明名称为Iinterface的分部接口的另外一部分。Iinterface接口的该部分代码包含一个名称为Age的属性。它的类型为int,并且该属性包含get和set访问器。

 public partial interface Iinterface

 {

     int Age

     {

         get;

         set;

     }

 }

上面共同声明了Iinterface接口。最终,Iinterface接口包含了两个属性:Name和Age。

处理同名成员

分部类型将一个类、结构或接口分成很多部分,但它们始终属于一个类、结构或接口的成员。因此,在不同部分中声明了同一个名称的成员,会发生编译时错误。除非该成员使用了partial修饰符。

下面声明一个名称为Program的分部类的一部分。Program类的该部分代码包含两个字段:name和age。name字段的类型为string,age字段的类型为int。另外,Program类的该部分代码还包含一个分部类:Test。Test分部类包含day字段。

 public partial class Program

 {

     string name;

     int age;

     public partial class Test        //声明Test分部类

     {

         int day;                            //day字段

     }

 }

下面声明一个名称为Program的分部类的另外一部分。Program类的该部分代码包含一个名称为age的字段,它的类型为int。另外,Program类的该部分代码还包含一个分部类:Test。Test分部类包含month和day字段。

 public partial class Program

 {

     int age;                //错误,因为Program分部类的另外一部分(在上面)已经声明该字段

     public partial class Test      //正确,因为Test为分部类,使用了partial修饰符

     {

         int month;                       //    month字段

         int day;                        //    day字段

     }

 }

上面的age字段将产生编译时错误,因为age字段已经在Program分部类的另外一部分声明。Test为分部类,使用了partial修饰符,因此,在声明Test分部类不会产生编译时错误。

处理基接口

一个分部类的各个部分可以指定不同的基接口,最终类型将实现所有分部声明所列出的全部接口。一个基接口在分部类型的一个部分中只能指定一次,但是可以在多个部分中同时被指定,即多个部分可以同时指定同一个基接口。

注意:在整个分部类型中,一个基接口的成员的实现只能是一个。但是,一个部分的基接口可以由另外一个部分提供该基接口的实现。

下面声明一个名称为Program的分部类。该分部类包含3个部分:

第一个部分实现Iinterface1接口、

第二个部分实现Iinterface2接口,

第三个部分实现Iinterface1和Iinterface2接口。

 public partial class Program:Iinterface1         //实现了Iinterface1接口

 {

 }

 public partial class Program:Iinterface2         //实现了Iinterface2接口

 {

 }

 public partial class Program:Iinterface1, Iinterface2          //实现了Iinterface1和Iinterface2接口

 {

 }

分部类Program的基接口集为Iinterface1、Iinterface2。

使用可空类型

在编程中,当处理未使用的字段时,通常只能使用占位值,或者使用附加字段指示某个字段是否已经使用。占位值只用于某个值无效的情况,而手动创建和管理附加字段会带来麻烦。可空类型完美地解决了如何辨识和处理不包含值的字段的问题。可空类型是一个特殊的值类型,由结构表示。它除了表示基础类型的所有值之外,还可以表示空值(null)。可空类型是System.Nullable<T>类型的对象,T必须是非可空值类型。声明可空类型存在以下两种形式。

(1)使用System.Nullable类声明可空类型的形式如下:

System.Nullable<T> variable

T表示可空类型的基础类型(underlying type),variable表示可空类型的变量的名称。

(2)使用?(问号)声明可空类型的形式如下:

T? variable

同上,T表示可空类型的基础类型,variable表示可空类型的变量的名称。

注意:T?是System.Nullable<T>的简写形式,它们的意义相同。

可空类型的基础类型不能是可空类型或者引用类型,它可以是以下两种类型。

非可空的值类型,如int、float等。

非可空值类型的类型参数,即具有struct约束的类型参数。

下面声明一个可空类型的变量day,它的基础类型为int。

int? day;             //声明一个可空类型的变量day

HasValue和Value属性

任何可空类型的实例都包含两个公共只读属性:HasValue和Value。它们的具体意义如下:

HasValue属性的类型为bool。它表示该实例是否包含一个确定值。如果HasValue属性的值为true,则表示该实例包含一个确定的值。否则,表示该实例为空,即它不包含确定的值。此时,如果要获取该实例的值,则发生运行时错误。Value属性的类型为该可空类型的基础类型。它表示该实例的一个确定的值,并作为该实例的值。

下面声明一个可空类型的变量day,它的基础类型为int。同时,设置该变量的值为10。

int? day = 10;            //声明一个可空类型的变量day并赋初值10

因为day变量已经被赋值为10,那么day变量的HasValue属性的值为true、Value属性的值为10。

当可空类型的实例的值为空时,如果通过Value属性获取该实例的值,会发生运行时错误。为了避免这种错误,因此在获取可空类型的实例的值时,首先需要判别该实例的值是否为空。

下面首先声明一个可空类型的变量day,它的基础类型为int;同时,设置该变量的值为10;然后获取day变量的值。在获取day变量的值之前,判断day变量是否包含确定的值(即判断day变量的HasValue属性的值是否为true)。如果存在确定的值(此时,day变量的HasValue属性的值为true),则获取day变量的值,并保存为d变量。

int? day = 10;

int d;

if(day.HasValue == true)     //判断day是否包含一个确定的值

{

    d = day.Value;             //使用Value属性获得day的值,将其赋给变量d

}

注意:任何可空类型都存在一个默认值。该默认值为一个实例,该实例的HasValue属性的值为false,Value属性的值是一个不确定的值。

GetValueOrDefault()方法

可空类型的实例只包含一个方法:GetValueOrDefault(),它可以用来获取可空类型的实例的值或默认值。它存在以下两种重载形式。

(1)public T GetValueOrDefault();

(2)public T GetValueOrDefault(T defaultValue)。

T表示可空类型的基础类型。

如果可空类型的实例的HasValue属性的值为true,则该方法返回该实例的值(即Value属性的值)。

如果可空类型的实例的HasValue属性的值为false,(1)方法返回该实例的默认值,(2)方法返回defaultValue参数的值。

下面首先声明两个可空类型的实例:i和f。其中,i实例的值被设置为10,f实例未被赋值,它的值为null。然后分别调用GetValueOrDefault()和GetValueOrDefault(T defaultValue)方法获取i和f实例的值,结果分别保存为resulti、resultf、resultit和resultft变量。

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            int? i = 10;
            float? f = null;
            int Resulti = i.GetValueOrDefault();
            float Resultf = f.GetValueOrDefault();
            int resulti = i.GetValueOrDefault(100);
            float resultf = f.GetValueOrDefault(100);
            Console.WriteLine(Resulti);
            Console.WriteLine(Resultf);
            Console.WriteLine(resulti);
            Console.WriteLine(resultf);
            Console.ReadLine();
        }
    }
}

由于i实例已经被赋值,它存在一个确定值,因此,Resulti和resulti变量的值都为10。f实例是未被赋值,因此,Resultf的值为f实例的默认值0,resultf的值为defaultValue参数的值(100)。

注意:不管可空类型的实例是否包含确定的值,GetValueOrDefault()方法都会返回一个值。当可空类型的实例不包含确定的值时,如果使用Value属性获取该实例的值,则发生异常。

bool?类型

bool?类型为可空布尔类型,它可以表示3个值:true、false和null。可空布尔类型提供了两个运算符:&和|。&运算符表示逻辑与,|运算符表示逻辑或。可空布尔类型的实例运算结果如下

  X        Y            X & Y       X | Y         X         Y         X & Y       X | Y
true    true          true         true       false    null       false        null
true    false        false        true       null      true       null         true
true    null          null          true       null      false     false        null
false   true         false        true       null      null       null          null
false   false        false        false        

注意:可空布尔类型的运算法则和SQL中True、False和NULL运算法则一致。

------- Windows Phone 7手机开发.Net培训、期待与您交流! ------- 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值