zoukankan      html  css  js  c++  java
  • 【C#进阶系列】10 属性

    属性分为无参属性和有参属性(即索引器)。

    属性相对于字段的优点不仅仅是为了封装,还可以在读写的时候做一些额外操作,缓存某些值或者推迟创建一些内部对象,也适用于以线程安全的方式访问字段。

    话说最基本的属性就不讲了,太平常了。

    基本上很多文章都是讲属性的好处的,所以下面就讲一下属性的不足

    属性不能作为out和ref传参。属性实质上是方法而不是字段,因为属性在编译后实际上是方法。

    属性可能花较长时执行,而字段访问则是立即完成。

    许多人使用属性是为了线程同步,这就可能造成线程永远终止,要线程同步就不要使用属性。

    如果属性所在类可以被远程访问,那么调用属性会非常慢。

    在上面这些情况下,应该优先使用方法而不是属性。

    并且《CLR via C#》的作者十分不推荐使用属性,而是使用方法。

    匿名类型

    先上一段匿名类型的代码

    var man=new {Name="Troy",Age=1};

    这段代码在C#编译器中会先推断Name和Age的类型,然后给他们分别创建私有字段,再然后就为这两个私有字段创建只读属性。然后就创建一个构造器初始化私有只读字段。

    并重写Object的Equals(判断每个字段是否都想等),GetHashCode(根据每个字段的哈希码生成哈希码)和ToString(返回“属性=值”对的以逗号分隔的列表)。

    如果编译器发现代码中定义了多个匿名类型,但是这些匿名类型的每个属性都具有相同的类型和名称以及顺序。那么实际上它只会创建一个匿名类型定义。

    Tuple类型

    在System命名空间中,有几个泛型Tuple(元组)类型,它们全部从Object派生,区别只在于元数的个数。

    和匿名对象一样,Tuple创建好后就不可变了(所有属性都是只读)。

    匿名对象的属性调用是通过具体的属性名,然而Tuple类型只能通过Item1这样的方式调用。例子如下:

            var man = new Tuple<string, int, string>("Troy", 1, "");//构造器方式
                var boy = Tuple.Create("Fuckboy", 3, "");//静态工厂方法创造
                Console.WriteLine(man.Item1);//Troy
                Console.WriteLine(man.Item2);//1
                Console.WriteLine(man.Item3);////匿名对象方式
                var myObj = new { Name = "Troy", Age = 1, Sex = "" };
                Console.WriteLine(myObj.Name);//Troy
                Console.WriteLine(myObj.Age);//1
                Console.WriteLine(myObj.Sex);////另一种组合键值对的方式,感觉像在写js
                dynamic obj = new System.Dynamic.ExpandoObject();
                obj.Name = "Troy";
                obj.Age = 1;
                obj.Sex = "";
                Console.WriteLine(obj.Name);//Troy
                Console.WriteLine(obj.Age);//1
                Console.WriteLine(obj.Sex);//
                Console.Read();

    有参属性(索引器)

    C#使用数组风格的语法来公开有参属性。

    CLR本身并不区分有参属性和无参属性,对它而言,每个属性都只是类型中定义的一对方法和一些元数据。而用数组风格的语法来玩有参属性是C#特有的,编译之后还是会编译成IL代码中的方法。

    JIT对属性的优化

    对简单的get和set访问其方法,JIT编译后会将访问其代码直接嵌入到调用属性的方法中,这样就避免了运行时发出调用所产生的开销。代价就是编译后的方法变得更大,可以想象一下调用属性的方法有很多个,那么嵌入的重复代码就有很多。

    所以我们应该在属性访问器里写的代码应该尽可能少,否则用方法也不错。如果这样做了,那么JIT这样优化后,生成的本机代码会变得更小,而且执行更快。

  • 相关阅读:
    latch与DFF
    数字逻辑综合DC脚本示例及解释
    当DiscuzNT遇上了Loadrunner(下)
    [C#学习]在多线程中如何调用Winform
    并发性测试工具
    当DiscuzNT遇上了Loadrunner(上)
    大型网站(高访问、海量数据)技术架构
    Load Runner下载
    Invoke 和 BeginInvoke 的真正涵义
    当DiscuzNT遇上了Loadrunner(中)
  • 原文地址:https://www.cnblogs.com/vvjiang/p/5272907.html
Copyright © 2011-2022 走看看