zoukankan      html  css  js  c++  java
  • 我并不是不闻不问![C#]

    我并不是不闻不问![C#]

    Written by Allen Lee

    我在《我只负责转换![C/C++]》一文从类型转换的角度展示了C/C++对程序员的信任,那么C#对程序员的信任程度又有多高呢?

    我们先来看一段C#代码:

    // Code #01

    public enum Alignment
    {
        Left,
        Center,
        Right
    }


    class Program
    {
        
    static void Main()
        
    {
            Alignment a 
    = (Alignment)(-1);
            Console.WriteLine(a);

            a 
    = 0;
            Console.WriteLine(a);

            a 
    = (Alignment)(1);
            Console.WriteLine(a);

            a 
    = (Alignment)(2);
            Console.WriteLine(a);

            a 
    = (Alignment)(3);
            Console.WriteLine(a);
        }

    }


    // Output:
    //
    // -1
    // Left
    // Center
    // Right
    // 3

    这段代码能够顺利编译并运行。从输出结果中,我们可以看出C#不会妨碍你进行非预期的枚举转换。只是你必须对你的行为进行负责,如果你进行了非预期的转换,你将得到非预期的输出;相反,如果转换是有意义的话,输出也将是有意义的。另外,0是被自动转换成对应的枚举类型,不需要我们动手。

    现在来看另一段C#代码:

    // Code #02

    public enum Alignment : byte
    {
        Left,
        Center,
        Right
    }


    class Program
    {
        
    static void Main()
        
    {
            Alignment a 
    = (Alignment)(-1);
            Console.WriteLine(a);
        }

    }

    这次,我们为Alignment指定了底层类型,编译器不再不闻不问了,它拒绝编译并留下这样一句话:

    error CS0221: Constant value '-1' cannot be converted to a 'Alignment' (use 'unchecked' syntax to override)

    跟之前的不同,程序员不应该由于疏忽导致这种溢出,如果你是有意这样做的,必须用unchecked语法明确告诉编译器:

    // Code #03
    // See Code #02 for Alignment.

    class Program
    {
        
    static void Main(string[] args)
        
    {
            
    unchecked
            
    {
                Alignment a 
    = (Alignment)(-1);
                Console.WriteLine(a); 
            }

        }

    }


    // Output:
    //
    // 255

    这次编译器就不抱怨了,不过,你也应该认真想一下,这种溢出转换是否真的有必要呢?

    那么,这种溢出转换在C++的国度又是怎样一番景象呢?请先看下面的C++代码:

    // Code #04

    #include 
    <string>
    #include 
    <iostream>

    enum _jb_prog_mode : unsigned short
    {
        PROGRAM_ONE,
        PROGRAM_TWO
    }
    ;

    int _tmain(int argc, _TCHAR* argv[])
    {
        
    // In C, the enum keyword is required
        
    // to declare a variable of type enumeration.
        
    // In C++, the enum keyword can be omitted.
        
    // The following expression is legal in C++ only.

        _jb_prog_mode e_prog_index 
    = (_jb_prog_mode)(-1);

        std::cout 
    << (unsigned short)e_prog_index << std::endl;

        
    return 0;
    }


    // Output:
    //
    // 65535

    这段代码能够正常编译并顺利运行。从输出结果中我们明显看到溢出,但编译器和运行时却没有半点声响。看来,C++对程序员的信任程度真的去到了巅峰之处。

    请注意,ANSI C不允许我们指定枚举的底层类型,所有枚举的底层类型都是int

    接下来我们看看注册表的读取,假定注册表有如下信息:

    [HKEY_LOCAL_MACHINE\SOFTWARE\Allen]
    "Name"="Allen Lee"
    "ID"=dword:00000584

    然后我们来看看下面的C#代码:

    // Code #05

    class Program
    {
        
    static void Main(string[] args)
        
    {
            RegistryKey rk 
    = Registry.LocalMachine.OpenSubKey("software\\Allen");

            
    object obj = rk.GetValue("Name");
            
    string nm = (string)obj;        // Convert_01
            
    // int nm = (int)obj;           // Convert_02
            Console.WriteLine(nm);

            obj 
    = rk.GetValue("ID");
            
    int id = (int)obj;              // Convert_03
            
    // string id = (string)obj;     // Convert_04
            Console.WriteLine(id);
        }

    }


    // Output:
    //
    // Allen Lee
    // 1412

    上面这段代码当然可以正常输出正确的结果。如果我们分别把Convert_01和Convert_03替换为Convert_02和Convert_04呢?编译器不会拒绝你的编译请求,但运行时会毫不犹豫地抛出InvalidCastException,并指出无法进行指定的类型转换。

    那么,C++在面对类似的情况又是如何应付的呢?有兴趣的朋友可以参照《我只负责转换![C/C++]》一文中给出的代码片断试验一下,你将体会到C++对程序员是何等的信任!

    结论?也正如本文的题目——

    我并不是不闻不问!

    与C/C++比起来,C#的确没有那么自由,然而,这些限制却为我们带来另一番的味道。究竟C#的这些限制是对我们的一种帮助还是一种缚束呢?这就见仁见智了。

    See also:

  • 相关阅读:
    字符串的格式化操作
    了解格式化输出,字符串和编码
    面试题2
    面试题1
    设计算法1
    C++ STL容器的理解
    网络是怎样连接的-路由器的附加功能
    网络是怎样连接的-路由器的包转发操作(下)
    网络是怎样连接的-路由器的包转发操作(上)
    网络是怎样连接的-交换机的包转发操作
  • 原文地址:https://www.cnblogs.com/allenlooplee/p/115517.html
Copyright © 2011-2022 走看看