• CLR Via CSharp读书笔记(10):属性


    自动实现的属性

    与直接声明一个名为Name的public String字段相比,AIP(Auto Implement Property)意味着创建了一个属性。访问该属性的任何代码实际都会调用get和set方法。以后如果决定自己实现get和/或set方法,访问属性的任何代码都不必重新编译。如果将Name声明为字段,以后又想把它更改为属性,那么访问字段的所有代码都必须重新编译,以便访问属性的方法。

    AIP的支持字段(private字段)的名称是有编译器决定的,而且每次重新编译代码,它都可能更改这个名称。在任何想要序列化或反序列化的类型中,都不要使用AIP功能。

    注意:如果使用AIP,属性必然是可读和可写的,即编译器会同时生成get和set方法。

    合理定义属性

    属性不能作为out或ref参数传递给方法;字段却可以。

    属性方法可能花费较长时间执行;字段的访问则总是立即完成。如果需要线程同步,就不应该使用属性,它可能造成线程永远终止。这种情况下,最好是使用方法。此外,如果类可以被远程访问,调用属性方法会非常慢,应该优先使用方法而不是属性。

    对象和集合初始化器

    Employee e = new Employee() { Name = "Jeff", Age = 45 };
    Employee e = new Employee { Name = "Jeff", Age = 45 };
    var table = new Dictionary<String, Int32>() { { "Jeff", 1 }, { "Kristin", 2 }, { "Adian", 3 } };

    Classroom classroom = new Classroom { Students = { "Jeff", "Kristin", "Adian" } };

    匿名类型

    使用简洁的语法来声明一个不可变(immutable)的元组类型。元组(tuple)类型时含有一组属性的类型,这些属性通常以某种方式相互关联。

    class Program
    {
        static void Main(string[] args)
        {
            var o1 = new { Name = "Jeff", Year = 1965 }; // 匿名类型
    
            var people = new[] { // 由于名称的同一性而创建的隐式类型的数组
                o1,
                new { Name = "Kristin", Year = 1970 },
                new { Name = "Adian", Year = 2003 },
                new { Name = "Grant", Year = 2008 }
            };
    
            Console.WriteLine("Name = {0}, Year = {1}", o1.Name, o1.Year);
        }
    }

    匿名类型自动生成的属性是只读的,而非可读可写,目的是防止对象的哈希码发生改变。

    System.Tuple类型:

    所有Tuple类型都实现了IStructuralEquatable, IStructuralComparable和IComparable接口。

    class Program
    {
        static void Main(string[] args)
        {
            var minmax = Minmax(6, 2);
    
            Console.WriteLine("Mix = {0}, Max = {1}", minmax.Item1, minmax.Item2);
        }
    
        private static Tuple<Int32, Int32> Minmax(Int32 a, Int32 b)
        {
            return new Tuple<Int32, Int32>(Math.Min(a, b), Math.Max(a, b));
        }
    }

    有参属性
    有参属性的get访问器方法接受一个或多个参数,set访问器方法接受两个或多个参数。C#语言将有参属性称为索引器,可以将索引器看做重载[]操作符的一种方式。
    和无参数型不同,类型可以提供多个重载的索引器,只要这些索引器的签名不同。C#只允许在对象的实例上定义索引器,而没有 提供静态索引器属性的语法,虽然CLR是支持静态有参属性的。
    编译器为索引器生成的方法名分别为get_Item和set_Item。类型如果提供了一个名为Item的属性,则可判断该类型提供了一个索引器。可以使用IndexerNameAttribute来重命名索引器属性。

    public sealed class BitArray
    {
        [IndexerName("Bit")]
        public Int32 this[Int32 bitPos]
        {
            get { return 0; }
        }
    
        [IndexerName("Bit")]
        public Boolean this[String bitPos]
        {
            get { return true; }
        }
    }

    调用属性访问器方法时的性能

    对于简单的get和set访问器方法,JIT编译器会将代码内联(inline)。这样,使用属性(而不是字段)就没有性能损失。JIT编译器调试时不会内联属性方法。

    C#不允许在定义属性时,引入自己的泛型类型参数,因为概念上讲不通。属性本应表示的是一项可供查询或设置的对象特征。一旦引入泛型类型参数,就意味着查询/设置行为发生改变。


     

  • 相关阅读:
    516. 最长回文子序列
    NC50493 环形石子合并
    NC16650 采药
    NC16664 合唱队形
    NC51170 石子合并
    148. 合并果子
    NC25138 子串查询
    二维数组对角线 的 规律
    如何讲一个网页转换为jpg?(图片!)
    Java两倍 犯错题
  • 原文地址:https://www.cnblogs.com/thlzhf/p/2805433.html
Copyright © 2020-2023  润新知