zoukankan      html  css  js  c++  java
  • C#学习笔记6

    1.结构:结构除了可以含有属性和字段,还可以包方法和构造器,但不能包含黠认(无参数}的构造器。有的时候(比如在实例化一个数组的时候)不会调用值类型的构造器,因为所有数组内存都转为用零来初始化,为了避免因为默认构造器只是偶尔调用而造成不一致,C#完全禁止了用户显式定义默认构造器,因为编译器会将声明时的实例字段赋值放到类型的构造器中进行。在构造器中必须对 struct中的所有字段进行初始化,如果没有做到这一点,就会产生编译错误,可查看Angle结构的代码。

    2.结构的继承与接口:所有值类型都是密封的,除此之外,所有值类型都派生自system.ValueType,这意味着struct的继承链息是从object到ValueType到struct。值类型还能实现接口,许多接口都是实现接口框架固定组成部分,比如 IComparilble 和IFormattable。

    3.装箱与拆箱:装箱就是把值类型变成引用类型,如下:

     (1) 首先在堆中分配好内存,它将用于存放值类型的数据以及少许额外开销;

     (2) 接着发生一次内存复制动作,栈上的值类型数据复制到堆上分配好的位置;

     (3) 最后,对象或接口引用得到更新,指向堆上的位置;

      拆箱就是把引用类型变成值类型,如下:根据定义,CIL 指令 unbox 只是对堆上的数据进行解引用,并不包括从堆复制到栈的动作。但在 C#语言中,太多数时候紧接着在拆箱之后发生一次复制动作。装箱和拆箱之所以重要,是因为装箱去对性能和行为造成一些影响。开发者可以通过查看CIL,在一个特定的代码片段中统计 box/unbox 指令的数量。在BoxAndUnbox()中的代码就存在多次的装箱与拆箱,这样编写的代码是不合理。

    4.枚举:枚举和其他值类型稍有不同,因为枚举的继承链是从System.ValueType到System.Enum,再到enum。

    5.枚举与字符串的转换:枚举ToString()后会输出枚举标识符,使用Enum.Parse或Enum.TryParse方法可以把字符串转化为枚举,后一个方法是.Net4.0新增的泛型方法。此中我们也可以使用Enum.IsDefined()方法来检查一个值是否包含在一个枚举中。

    6.枚举作为“位标志”使用:

    (1)可以查看如下“FileAttributes“枚举的设定(即System.IO。FileAttributes的设定),作为位标志后,其值可以自由组合,所以可以使用Or运算符来联结枚举值。如本示例中BitFlag()方法的使用。当然枚举中的每个值不一定只对应一个标志,完全可以为常用的标志组合定义额外的枚举值。

    (2)使用位标志类型的时候,位标志枚举应该包含[FlagsAttribute]这个特性,这个标志指出多个枚举值可以组合使用,此外,它改变了ToString()和Parse()方法的行为。例如为一个已用FlagsAttribute修饰了的枚举调用ToString()方法,会为已设置的每个枚举标志输出对应的字符串(如BitFlag2()的示例),而如果没有这个修饰,返回的就是组合后数值。

    public struct Angle
    {
        public Angle(int hours, int minutes, int seconds)
        {
            Hours = hours;
            Minutes = minutes;
            Seconds = seconds;
        }
        public int Hours { get; set; }
        public int Minutes { get; set; }
        public int Seconds { get; set; }
    
        public Angle Move(int hours, int minutes, int seconds)
        {
            return new Angle(Hours + hours, Minutes + minutes, Seconds + seconds);
        }
    }
    
    [Flags]
    public enum FileAttributes
    {
        ReadOnly = 1 << 0,
        Hidden = 1 << 1,
        System = 1 << 2,
        Directory = 1 << 3,
        Archive = 1 << 5,
        Device = 1 << 6,
        Normal = 1 << 7,
        Temporary = 1 << 8,
        SparseFile = 1 << 9,
        ReparsePoint = 1 << 10,
        Compressed = 1 << 11,
        Offline = 1 << 12,
        NotContentIndexed = 1 << 13,
        Encrypted = 1 << 14
    }
    
    public void BitFlag()
    {
        string fileName = @"enumtest.txt";
        FileInfo file = new FileInfo(fileName);
        file.Attributes = FileAttributes.Hidden | FileAttributes.ReadOnly;
        Console.WriteLine("{0} | {1} = {2}", FileAttributes.Hidden, FileAttributes.ReadOnly, (int)file.Attributes);
        if ((file.Attributes & FileAttributes.Hidden) != FileAttributes.Hidden)
        {
            throw new Exception("File is not hidden");
        }
        if ((file.Attributes & FileAttributes.ReadOnly) != FileAttributes.ReadOnly)
        {
            throw new Exception("File is not read-only");
        }
        //....
    }
    
    public void BitFlag2()
    {
        string fileName = @"enumtest.txt";
        FileInfo file = new FileInfo(fileName);
        file.Open(FileMode.Create).Close();
        FileAttributes startingAttributes = file.Attributes;
        file.Attributes = FileAttributes.Hidden | FileAttributes.ReadOnly;
        Console.WriteLine(""{0}" output as "{1}"", file.Attributes.ToString().Replace(",", "|"), file.Attributes);
        FileAttributes attributes;
        Enum.TryParse(file.Attributes.ToString(), out attributes);
        Console.WriteLine(attributes);
        File.SetAttributes(fileName, startingAttributes);
        file.Delete();
    }
    
    public void BoxAndUnbox()
    {
        int totalCount;
        ArrayList list = new ArrayList();
        Console.Write("Enter a number between 2 to 1000:");
        totalCount = int.Parse(Console.ReadLine());
        list.Add((double)0);
        list.Add((double)1);
        for (int i = 2; i < totalCount; i++)
        {
            list.Add((double)list[i - 1] + (double)list[i - 2]);
        }
        foreach (double num in list)
        {
            Console.Write("{0},", num);
        }
    }

    ----------------------以上内容根据《C#本质论 第三版》进行整理

  • 相关阅读:
    再谈TextField
    IOS-TextField知多少
    leftBarButtonItems
    LeftBarButtonItems,定制导航栏返回按钮
    Apple Mach-O Linker (id) Error "_OBJC_CLASS...错误解决办法 Apple Mach-O Linker (id) Error "_OBJC_CLASS...错误解决办法
    Unrecognized Selector Sent to Instance问题之诱敌深入关门打狗解决办法
    UNRECOGNIZED SELECTOR SENT TO INSTANCE 问题快速定位的方法
    Present ViewController,模态详解
    UILABEL AUTOLAYOUT自动换行 版本区别
    iOS自动布局解决警告Automatic Preferred Max Layout Width is not available on iOS versions prior to 8.0
  • 原文地址:https://www.cnblogs.com/zwt-blog/p/6305833.html
Copyright © 2011-2022 走看看