• 使用关节型


    使用关节型

    能力 C# 使用union类型。但,因为 C# 有联合类型没有真正意义上。故。于 C# 别看美丽的使用。

    在本节。我们将讨论如何 C# 使用union类型。除了作为一个库设计师。如何决定是否打开关节类型库(尽管,我个人建议避免跨语言公开联合类型)。

    第一个样例,我们定义了一个简单的联合类型Quantity,它有两个构造函数,一个包括整数,还有一个包括浮点数。还提供一个函数getRandomQuantity()。初始化 Quantity 的新实例。

     

    module Strangelights.DemoModule

    open System

     

    // type that can represent a discrete or continuousquantity

    type Quantity =

    | Discrete of int

    | Continuous of float

     

    // initalize random number generator

    let rand = new Random()

    // create a random quantity

    letgetRandomQuantity() =

        match rand.Next(1) with

        | 0 ->Quantity.Discrete (rand.Next())

        | _ ->

           Quantity.Continuous

               (rand.NextDouble() * float_of_int (rand.Next()))

     

    尽管,我们提供了getRandomQuantity() 去创建 Quantity 类型的新版本号,可是。类型自身也提供了静态方法,去创建组成这个类型的不同构造函数的新实例。这些静态方法在全部联合类型上都可用,它缺省由程序集公开,不须要做不论什么特别的事情,让编译器去创建它。以下的样例演示了怎样从 C# 中使用这些方法:

     

    using System;

    using Strangelights;

     

    static class GetQuantityZeroClass

    {

        public static void GetQuantityZero()

        {

            // initialize both aDiscrete and Continuous quantity

            DemoModule.Quantity d = DemoModule.Quantity.Discrete(12);

            DemoModule.Quantity c = DemoModule.Quantity.Continuous(12.0);

        }

    }

     

    如今,我们已经知道怎样从 C# 中创建联合类型,因此。以下最重要的任务就是决定构造函数属于哪一个特定的Quantity 值。能够有三种方法,以下的两段代码,我先讨论前两种方法,第三种方法要放在本节的最后。

    第一种方法是能够对值的Tag 属性的分支选择(switch)。

    这个属性是整数,可是。由于联合类型的编译版本号提供的是常量,总是有tag_ 前缀,帮助识别这个整数的含义。因此,假设想使用Tag 属性去找出是哪种类型的Quantity,通常写一个switch 语句,如以下的样例所看到的:

     

    //!!! C# Source !!!

    using System;

    using Strangelights;

     

    static class GetQuantityOneClass

    {

        public static void GetQuantityOne()

        {

            // get a randomquantity

            DemoModule.Quantity q = DemoModule.getRandomQuantity();

     

            // use the .Tagproperty to switch over the quatity

            switch (q.Tag)

            {

                case DemoModule.Quantity.tag_Discrete:

                    Console.WriteLine("Discretevalue: {0}",q.Discrete1);

                    break;

                case DemoModule.Quantity.tag_Continuous:

                    Console.WriteLine("Continuousvalue: {0}",q.Continuous1);

                    break;

            }

        }

    }

     

    这个样例的执行的结果例如以下:

    Discrete value: 65676

     

    假设我们愿意,联合类型的编译形式也提供了一系列方法。前缀都是Is,用測试一个值是否属于联合类型中的特定构造函数。

    比如,在联合类型Quantity 中,有两个方法,IsDiscrete() 和IsContinuous()。測试Quantity 是属于Discrete,还是Continuous。

    以下的样例就演示了怎样使用:

     

    //!!! C# Source !!!

    using System;

    using Strangelights;

     

    static class GetQuantityTwoClass

    {

        public static void GetQuantityTwo()

        {

            // get a randomquantity

            DemoModule.Quantity q = DemoModule.getRandomQuantity();

            // use if ... elsechain to display value

            if (q.IsDiscrete())

            {

                Console.WriteLine("Discretevalue: {0}",q.Discrete1);

            }

            else if (q.IsContinuous())

            {

                Console.WriteLine("Continuousvalue: {0}",q.Continuous1);

            }

        }

    }

     

    演示样例的执行结果例如以下:

    Discrete value: 2058

    由于运行模式匹配所需的代码量过大,所以。这两种方法都不特别令人惬意;且还有风险。假设写的代码例如以下所看到的,检測值是否是Discrete,但错误地使用了Continuous1 属性,就会出错。导致了NullReferenceException 异常。

     

    DemoModule.EasyQuantity q = DemoModule.getRandomEasyQuantity();

    if (q.IsDiscrete())

    {

        Console.WriteLine("Discretevalue: {0}", q.Continuous1);

    }

     

    为给库用户提供很多其它的保障,为联合类型加入成员,运行模式匹配,是一个好办法。以下的样例改动了Quantity 类型,产生新类型EasyQuantity,加入两个成员,把类型转换成整数或浮点数:

     

    module Strangelights.ImprovedModule

    open System

     

    //type that can represent a discrete or continuous quantity

    //with members to improve interoperability

    type EasyQuantity =

    |Discrete of int

    |Continuous of float

      // convert quantity to a float

      member x.ToFloat() =

        match x with

        | Discrete x -> float x

        | Continuous x -> x

      // convert quantity to a integer

      member x.ToInt() =

        match x with

        | Discrete x -> x

        | Continuous x -> int x

     

    //initalize random number generator

    let rand = new Random()

     

    //create a random quantity

    letgetRandomEasyQuantity() =

      match rand.Next(1) with

      | 0 -> EasyQuantity.Discrete (rand.Next())

      | _ ->

            EasyQuantity.Continuous

              (rand.NextDouble() * float(rand.Next()))

     

    这样,库用户既可把值转换成整数。也能够转换成浮点数,而不必操心模式匹配,就像以下的样例:

     

    //!!! C# Source !!!

    using System;

    using Strangelights;

     

    class GetQuantityThreeClass

    {

        public static void GetQuantityThree()

        {

            // get a randomquantity

            ImprovedModule.EasyQuantity q = ImprovedModule.getRandomEasyQuantity();

            // convert quantityto a float and show it

            Console.WriteLine("Value as afloat: {0}",q.ToFloat());

        }

    }

    [

    所有样品都没有经过测试的演示。

    ]

  • 相关阅读:
    android自定义Dialog
    go笔记-内存回收分析、内存统计信息字段释义
    go笔记-defer以及性能
    go笔记-goroutine和panic
    并发编程-高性能IO-reactor模式
    go笔记-查看coredump:delve调试工具
    IO多路复用[转]
    kubernates 1.20.6安装
    JavaScript 数组元素的一些操作
    如何理解 Java 多线程
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4813569.html
Copyright © 2020-2023  润新知