深入理解C#3.x的新特性(4):Automatically Implemented Property-阿里云开发者社区

开发者社区> 行者武松> 正文

深入理解C#3.x的新特性(4):Automatically Implemented Property

简介:
+关注继续查看
深入理解C#3.x的新特性系列在沉寂一个月之后,今天继续。在本系列前3部分中,我们分别讨论了Anonymous TypeExtension Method Lambda Expression,今天我们来讨论另一个实用的、有意思的New featureAutomatically Implemented Property

一、繁琐的private field + public property Definition

相信大家大家已经习惯通过一个private field + public property的发式来定义和实现一个public Property。就像下面一个Artech.AutoImpProperty. Point

namespace Artech.AutoImpProperty
{
    public class Point
    {
        private double x;
        private double y;    

        public double X
        {
            get
            {
                return this.x;
            }

            set
            {
                this.x = value;
            }

        }

        public double Y
        {
            get return y; }
            set { y = value; }
        }


        public Point(double x, double y)
        {
            this.x = x;
            this.y = y;
        }

    }

}


虽然在Property中的set/get block中,我们可以不受限制地定义我们的业务逻辑,但是在大多是场合下,我们都是像上面的code一样直接对一个定义的field进行操作:在get block中返回field的值,在set block中对field赋值。也就是说,我们大多数还是将Property作为它所对应的field的直接封装。在说道Property的定义,我顺便提一下我们定义Property的一个原则:Property中的操作应该是立即能够执行完成的,我们不应该将一些Time consuming的操作放在一个Property中。因为我曾经看到过有人把调用Web Service的操作放在Property中,这是不知的推荐的,像这样的操作应该封装在一个Method中。

把话题转到我们简单的private field + public property Definition上来。如果我们定义一个Class中,只需要定义一个这样的Property,我们通过上面的code去定义可能觉得没什么。但是如果我们的Class,尤其是作为Business EntityClass,需要封装非常多的数据,我们需要为不同类型的数据分别定义一个Property,这样不断重复的工作大家一定觉得很厌烦。虽然我们的IDE-VS 2005VS 2008 beta 2通过Encapsulate Field的方式为我们的Coding工作减轻了负担(不清楚该小技巧的朋友可以参见下图),但是能在Programming Language级别就能够去除掉这些重复的定义得花,不但从根本上使Developer得到解脱,还能使我们的程序变得更加简洁和优雅。现在我们这一点我们可以做到了。


二、没有FieldAutomatically Implemented Property Definition

C# 3.x中,借助它提供的Automatically Implemented Property新特性,我们可以从繁琐的、重复的Coding工作中解脱出来了。我们来看我们先在的Property有多简单: Artech.AutoImpProperty. Vector

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Artech.AutoImpProperty
{
    class Program
    {
        static void Main(string[] args)
        {
            Vector v = new Vector(1, 2);
            Console.WriteLine("X = {0} and Y = {1}", v.X, v.Y);
        }

    }


    public class Vector
    {
        public double X getset; }
        public double Y getset; }

        public Vector(double x, double y)
        {
            this.X = x;
            this.Y = y;
        }

    }
    
    }

}

通过上面的Code,我们大家能够体会到Automatically Implemented Property为我们定于Property带来的价值了吧。首先Property对应的Field从跟上上省去了;在set/get我们只需要一个申明式的语句,而不在需要去实现它(Automatically Implemented)。而我们定义的Artech.AutoImpProperty. Vector和上面定义的Artech.AutoImpProperty. Point是完全等效的

三、Backing Field成就了Automatically Implemented Property

从上面我们提供的Code的对比,我们可以很直观的体会到Automatically Implemented Property的实用价值。我现在来讨论一下这样的功能在技术上是如何实现的。

如果读过本系列前面3篇文章的朋友,一定记得我经常在重复这样的观点:C#3.x仅仅是基于.NET Programming Language,而不是基于.NET Framework的。换句话说,就是.NET Programming Language对于得编译器在编译的时候给我们玩了一个“障眼法”:加了一些必要的code,使原本我们看起来显得残缺的code(比如缺少对Property 的实现)变得完整。在运行的时候,这些code和原来的code是完全一样的。

为了使大家对Automatically Implemented Property的实现有一个直观的了解,我们把基于两种不同的Property definitionClass放到一起:传统的Field-based Explicit Implemented Property V.S. Automatically Implemented Property

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Artech.AutoImpProperty
{
    class Program
    {
        static void Main(string[] args)
        {
            Vector v = new Vector(1, 2);
            Console.WriteLine("X = {0} and Y = {1}", v.X, v.Y);
        }

    }


    public class Vector
    {
        public double X getset; }
        public double Y getset; }

        public Vector(double x, double y)
        {
            this.X = x;
            this.Y = y;
        }

    }


    public class Point
    {
        private double x;
        private double y;    

        public double X
        {
            get
            {
                return this.x;
            }

            set
            {
                this.x = value;
            }

        }

        public double Y
        {
            get return y; }
            set { y = value; }
        }


        public Point(double x, double y)
        {
            this.x = x;
            this.y = y;
        }

    }

}

现在我们先通过Reflector来看看在最终编译生成的Assembly中,Artech.AutoImpProperty. PointArtech.AutoImpProperty. Vector到底有何不同:

通过上图我们可以看到:Artech.AutoImpProperty. Point和我们在Source code定义的一致, 具有两个PropetyXY)和对应的Fieldxy)。但是对于我们通过Automatically Implemented Property方式定义的Artech.AutoImpProperty. Vetor就有点特别了:虽然在Source Code中我们只定义了两个PropertyXY),不曾对应任何的Field。但是现在却凭空多处两个Field<X>k__BackingField <Y>k__BackingField。看到这两个多出来的banking field,我们不难想象他们的作用了:他们分别对应着我们定义的两个PropertyXY),其作用和Artech.AutoImpProperty. Point中定义的两个Fieldxy)完全一样。我们可以通过在ReflectorDisassemble Artech.AutoImpProperty. Vetor查看其最终的C# Code

public class Vector
{
    // Fields
    [CompilerGenerated]
    private double <X>k__BackingField;
    [CompilerGenerated]
    private double <Y>k__BackingField;

    // Methods
    public Vector(double x, double y)
    {
        this.X = x;
        this.Y = y;
    }


    // Properties
    public double X
    {
        [CompilerGenerated]
        get
        {
            return this.<X>k__BackingField;
        }

        [CompilerGenerated]
        set
        {
            this.<X>k__BackingField = value;
        }

    }


    public double Y
    {
        [CompilerGenerated]
        get
        {
            return this.<Y>k__BackingField;
        }

        [CompilerGenerated]
        set
        {
            this.<Y>k__BackingField = value;
        }

    }

}


C# 3.x相关内容:
[原创]深入理解C# 3.x的新特性(1):Anonymous Type
[原创]深入理解C# 3.x的新特性(2):Extension Method - Part I
[原创]深入理解C# 3.x的新特性(2):Extension Method - Part II
[原创]深入理解C# 3.x的新特性(3):从Delegate、Anonymous Method到Lambda Expression
[原创]深入理解C# 3.x的新特性(4):Automatically Implemented Property
[原创]深入理解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

作者:蒋金楠
微信公众账号:大内老A
微博:www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
10024 0
「机器人视觉」带你深入了解机器人视觉系统工作原理及其应用
人类想要实现一系列的基本活动,如生活、工作、学习就必须依靠自身的器官,除脑以外,最重要的就是我们的眼睛了,(工业)机器人也不例外,要完成正常的生产任务,没有一套完善的,先进的视觉系统是很难想象的。 人类想要实现一系列的基本活动,如生活、工作、学习就必须依靠自身的器官,除脑以外,最重要的就是我们的眼睛了,(工业)机器人也不例外,要完成正常的生产任务,没有一套完善的,先进的视觉系统是很难想象的。
1328 0
《深入理解C++11:C++ 11新特性解析与应用》——2.9 扩展的friend语法
本节书摘来自华章计算机《深入理解C++11:C++ 11新特性解析与应用》一书中的第2章,第2.9节,作者 IBM XL编译器中国开发团队,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
1476 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13837 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
11881 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
7347 0
+关注
行者武松
杀人者,打虎武松也。
17142
文章
2569
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载