C#中的属性解析(get、set、value)

目录
  • C#中的属性(get、set、value)
  • C#中属性的定义

C#中的属性(get、set、value)

C#语言在面向对象设计和编程中对数据安全提出了严格的要求,其中一个重要的原则就是数据封装。根据这一原则,C#程序设计中要求开发人员对特定类的数据字段尽量不以公有方式提供给外界。因此在类内部多数字段的访问权限被限定为private或是public,而这些字段与外界的交流经常采用属性来进行。

属性使类能够以一种公开的方法获取和设置值,同时隐藏实现或验证代码。

属性是这样的成员:它们提供灵活的机制来读取、编写或计算私有字段的值。

可以像使用公共数据成员一样使用属性,但实际上它们是称作“访问器”的特殊方法。这 使得可以轻松访问数据,此外还有助于提高方法的安全性和灵活性。

属性使类能够以一种公开的方法获取和设置值,同时隐藏实现或验证代码。

get 属性访问器用于返回属性值,而 set 访问器用于分配新值。 这些访问器可以有不同的访问级别。

get 访问器体与方法体相似。 它必须返回属性类型的值。执行 get 访问器相当于读取字段的值

get 访问器必须以 return 或 throw 语句终止,并且控制权不能离开访问器体。

value 关键字用于定义由 set 取值函数分配的值。

不实现 set 取值函数的属性是只读的。

属性的定义通常由以下两部分组成:

1、需要封装的专用数据成员

private int _nValue = 1;
private double _dValue = 10.101;
private char _chValue = 'a';

2、向外界提供访问的公共属性:

//读写属性nValue:
public int nValue
{
    get
    {
        return _nValue;
    }
    set
    {
        _nValue = value;
    }   
}
//只读属性dValue:
public double dValue
{
    get
    {
        return _dValue;
    }
}
//只写属性chValue:
public char chValue
{
    set
    {
        _chValue = value;
    }
}

当属性的访问器中不需要其他逻辑时,自动实现的属性可使属性声明更加简洁。客户端还可以通过这些属性创建对象,例如下面的代码,编译器将创建一个私有的匿名支持字段,该字段只能通过属性的get和set访问器进行访问。

class Customer
{   // Auto-Impl Properties for trivial get and set
    public double TotalPurchases { get; set; }
    public string Name { get; set; }
    public int CustomerID { get; set; }
    // Constructor
    public Customer(double purchases, string name, int ID)
    {
        TotalPurchases = purchases;
        Name = name;
        CustomerID = ID;
    }
    // Methods
    public string GetContactInfo() {return "ContactInfo";}
    public string GetTransactionHistory() {return "History";}
    // .. Additional methods, events, etc.
}
class Program
{
    static void Main()
    {
        // Intialize a new object.
        Customer cust1 = new Customer ( 4987.63, "Northwind",90108 );
        //Modify a property
        cust1.TotalPurchases += 499.99;
    }
}

下面讲一个如何使用自动实现的属性实现轻量类:

此示例演示如何创建一个不可变轻量类,用于仅封装一组自动实现的属性。当您必须使用引用类型语义时,请使用此种构造而不是结构。

请注意:对于自动实现的属性,需要 get 和 set 访问器。 要使该类不可变,请将 set 访问器声明为 private。 但是,声明私有 set 访问器时,不能使用对象初始值来初始化属性。

下面的示例演示两种方法来实现具有自动实现属性的不可变类。第一个类使用构造函数初始化属性,第二个类使用静态工厂方法。

class Contact
      {
          // Read-only properties.
          public string Name { get; private set; }
          public string Address { get; private set; }
          // Public constructor.
          public Contact(string contactName, string contactAddress)
          {
              Name = contactName;
              Address = contactAddress;               
          }
      }
      // This class is immutable. After an object is created,
      // it cannot be modified from outside the class. It uses a
      // static method and private constructor to initialize its properties.   
      public class Contact2
      {
          // Read-only properties.
          public string Name { get; private set; }
          public string Address { get; private set; }
          // Private constructor.
          private Contact2(string contactName, string contactAddress)
          {
              Name = contactName;
              Address = contactAddress;               
          }
          // Public factory method.
          public static Contact2 CreateContact(string name, string address)
          {
              return new Contact2(name, address);
          }
      }
      public class Program
      { 
          static void Main()
          {
              // Some simple data sources.
              string[] names = {"Terry Adams","Fadi Fakhouri", "Hanying Feng", 
                                "Cesar Garcia", "Debra Garcia"};
              string[] addresses = {"123 Main St.", "345 Cypress Ave.", "678 1st Ave",
                                    "12 108th St.", "89 E. 42nd St."};
              // Simple query to demonstrate object creation in select clause.
              // Create Contact objects by using a constructor.
              var query1 = from i in Enumerable.Range(0, 5)
                          select new Contact(names[i], addresses[i]);
              // List elements cannot be modified by client code.
              var list = query1.ToList();
              foreach (var contact in list)
              {
                  Console.WriteLine("{0}, {1}", contact.Name, contact.Address);
              }
              // Create Contact2 objects by using a static factory method.
              var query2 = from i in Enumerable.Range(0, 5)
                           select Contact2.CreateContact(names[i], addresses[i]);
              // Console output is identical to query1.
              var list2 = query2.ToList();
              // List elements cannot be modified by client code.
              // CS0272:
              // list2[0].Name = "Eugene Zabokritski"; 
              // Keep the console open in debug mode.
              Console.WriteLine("Press any key to exit.");
              Console.ReadKey();                
          }
      }
  /* Output:
    Terry Adams, 123 Main St.
    Fadi Fakhouri, 345 Cypress Ave.
    Hanying Feng, 678 1st Ave
    Cesar Garcia, 12 108th St.
    Debra Garcia, 89 E. 42nd St.
*/

上诉中,通过get存取器和set存取器将封装好的专有数据成员和共同属性关联起来。

此时,value关键字是时候出场了。

在普通的C#程序中,一般不能通过常用的调试手段获得value值传递的详细过程,不能像C++中一样跟踪指针的变化情况。当使用如下语句给属性赋值:

Class ValueCollector{...};
ValueCollector newValue = new ValueCollector();
newValue.nValue = 10;

新对象newValue的私有数据成员_nValue通过属性nValue的set方法由原来的1改变为10;

赋值语句的右值通过隐式参数value进入属性set方法内,成功改变整型私有变量的值。

在这一过程中,value参数的类型是整型,与属性的类型是一致的。当属性的类型改变为char,value参数的属性也相应的改变为字符型。

这种参数类型的自动转换时基于.NETFramework提供的类型转换器而实现的,CLR将C#源代码编译成中间语言IL,在这种类汇编的高级机器语言中可以发现value参数的传递机制。

C#中属性的定义

属性的定义

定义结构:

public int MyIntProp{
    get{
            //get code
        }
    set{
            //set code
        }
    }
  • 定义属性需要名字和类型。
  • 属性包含两个块:get块和set块。
  • 访问属性和访问字段一样,当取得属性的值得时候,就会调用属性中的get块,因此get块需要返回值,其返回值类型就是属性的类型;当我们去给属性设置值得时候,就会调用属性中的set块,以此可以在set块中通过value访问到我们所设置的值。

eg:

//跟访问字段的方式一样
v1.MyIntProperty = 600; //对属性设置值,自动调用set块
int temp = v1.MyIntProperty //对属性取值,自动调用get块

需要注意的是,set方法和get方法可以不同时存在。

但是如果没有get块,就不可以获得取值;如果没有set块,就不能进行设置值。

通过属性访问字段

一般而言,习惯于将字段设置为private,这样外界就不能修改字段的值。这是我们可以通过定义属性来设置字段和获取字段的值。

eg:

private int age;
public int Age{ //习惯字段小写,属性大写
    set{
        if(value<0) return;   //通过set值进行一些校验的工作
        age = value;
        }
    get{
        return age;
        }
    }

设置属性的只读或者只写

只读

private string name;
public string Name{
    get{
            return name;
        }

只写

private string name;
public string Name{
    set{
            name = value;
        }

属性的访问修饰符

//如果在get或set块钱加上private,表示这个块只能在类内进行调用
public float X{
    private set { x = value;}  
    get { return x;}
public float X{
    set { x = value;}  
    private  get { return x;}  

自动实现的属性

public int Age{set;get;}    //编译器会自动提供字段来存储age
-->等价于
public int Age{
    set{ age = value;}
    get{ return age;}

总结一下,属性就相当于是一种带有set和get方法的一个方法,而它与类中的字段的赋值和取值又是息息相关的。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • C#之set与get方法的用法案例

    需求:学生输入姓名和语文.数学.英语,编程求出总分和平均分,并在屏幕上显示XX的总分和平均分 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; //学生输入姓名和语文.数学.英语,编程求出总分和平均分,并在屏幕上显示XX的总分和平均分 namespace Student_management_system { cla

  • C#反射(Reflection)对类的属性get或set值实现思路

    近段时间,有朋友叫Insus了解一下反射(Reflection)方面的知识,反射提供了封装程序集.模块和类型的对象(Type类型).可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性.如果代码中使用了属性,可以利用反射对它们进行访问. 下面的例子,是Insus练习对一个类别的属性进行set和get值. 首先写一个类,再写一个可读写的属性: 复制代码 代码如下: using System; using System.Collections.Ge

  • 深入C#中get与set的详解

    释一:属性的访问器包含与获取(读取或计算)或设置(写)属性有关的可执行语句.访问器声明可以包含 get 访问器或 set 访问器,或者两者均包含.声明采用下列形式之一:get {}set {}get 访问器get 访问器体与方法体相似.它必须返回属性类型的值.执行 get 访问器相当于读取字段的值.以下是返回私有字段 name 的值的 get 访问器: 复制代码 代码如下: private string name;   // the name fieldpublic string Name  

  • C#中{get;set;}的具体使用

    在C#程序中经常会看到set,get的配套使用,很多人不知道它的用途.我就在这向大家讲讲,也加深一下自己的印象. //这里有两个类 public class person1 { public string name; } public class person2 { public string Name{set;get;} } 我们可以看到,第一个类中的name是没有封装的,第二给则用到{get;set;}  关键字进行封装.其实含义也是很简单,get与set分别对应的是可读与可写.其实以前的代

  • C#中的属性解析(get、set、value)

    目录 C#中的属性(get.set.value) C#中属性的定义 C#中的属性(get.set.value) C#语言在面向对象设计和编程中对数据安全提出了严格的要求,其中一个重要的原则就是数据封装.根据这一原则,C#程序设计中要求开发人员对特定类的数据字段尽量不以公有方式提供给外界.因此在类内部多数字段的访问权限被限定为private或是public,而这些字段与外界的交流经常采用属性来进行. 属性使类能够以一种公开的方法获取和设置值,同时隐藏实现或验证代码. 属性是这样的成员:它们提供灵活

  • Python中property属性实例解析

    本文主要讲述的是对Python中property属性(特性)的理解,具体如下. 定义及作用: 在property类中,有三个成员方法和三个装饰器函数. 三个成员方法分别是:fget.fset.fdel,它们分别用来管理属性访问: 三个装饰器函数分别是:getter.setter.deleter,它们分别用来把三个同名的类方法装饰成property. fget方法用来管理类实例属性的获取,fset方法用来管理类实例属性的赋值,fdel方法用来管理类实例属性的删除: getter装饰器把一个自定义类

  • Spring中Xml属性配置的解析全过程记录

    1 工程概述 1.1 pom文件 <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <spring.ver

  • Vue中监视属性和计算属性区别解析

    目录 计算属性 需求 使用watch实现 准备工作 测试 测试 在computed当中书写 总结 计算属性 顾名思义,计算属性就是计算出来的属性,英文名儿computed这里要和data和methods里的东西区分,data里的属性,methods里的函数,你写的都会原封不动放到vm里,但是computed里面的东西写的是对象,最后放到vm里的是这个对象的名,值是get里的返回值. 下面看下Vue中监视属性和计算属性区别. 需求 我们将计算属性的案例使用watch写一遍 需求一揽 两个输入框 下

  • 深入理解JavaScript中的预解析

    前言 JavaScript是解释型语言是毋庸置疑的,但它是不是仅在运行时自上往下一句一句地解析的呢? 事实上或某种现象证明并不是这样的,通过<JavaScript权威指南>及网上相关资料了解到,JavaScript有"预解析"行为.理解这一特性是很重要的,不然在实际开发中你可能会遇到很多无从解析的问题,甚至导致程序bug的存在.为了解析这一现象,也作为自己的一次学习总结,本文逐步引导你来认识JavaScript"预解析",如果我的见解有误,还望指正. 在

  • JavaScript中的正则表达式解析

    JavaScript中的正则表达式解析 正则表达式(regular expression)对象包含一个正则表达式模式(pattern).它具有用正则表达式模式去匹配或代替一个字符串(string)中特定字符(或字符集合)的属性(properties)和方法(methods).要为一个单独的正则表达式添加属性,可以使用正则表达式构造函数(constructor function),无论何时被调用的预设置的正则表达式拥有静态的属性(the predefined RegExp object has s

  • java中使用sax解析xml的解决方法

    在java中,原生解析xml文档的方式有两种,分别是:Dom解析和Sax解析 Dom解析功能强大,可增删改查,操作时会将xml文档以文档对象的方式读取到内存中,因此适用于小文档 Sax解析是从头到尾逐行逐个元素读取内容,修改较为不便,但适用于只读的大文档 本文主要讲解Sax解析,其余放在后面 Sax采用事件驱动的方式解析文档.简单点说,如同在电影院看电影一样,从头到尾看一遍就完了,不能回退(Dom可来来回回读取) 在看电影的过程中,每遇到一个情节,一段泪水,一次擦肩,你都会调动大脑和神经去接收或

  • javaScript中的原型解析【推荐】

    最近在学习javaScript,学习到js面向对象中的原型时,感悟颇多.若有不对的地方,希望可以指正. js作为一门面向对象的语言,自然也拥有了继承这一概念,但js中没有类的概念,也就没有了类似于java中的extends,所以,我觉得js中的继承主要依赖于js中的原型(链). 那么,原型是什么呢?我们知道js中函数亦是一种对象,当我们创建一个函数时,其实这个函数也就默认的拥有了一个属性叫做prototype,这个属型叫做原型属性,他是一个指针,指向了这个函数的原型对象,这个原型对象有一个默认的

  • 在java中使用dom解析xml的示例分析

    dom是个功能强大的解析工具,适用于小文档 为什么这么说呢?因为它会把整篇xml文档装载进内存中,形成一颗文档对象树 总之听起来怪吓人的,不过使用它来读取点小东西相对Sax而言还是挺方便的 至于它的增删操作等,我是不打算写了,在我看教程的时候我就差点被那代码给丑到吐了 也正因为如此,才有后来那些jdom和dom4j等工具的存在-- 不多说,直接上代码 Dom解析示例 复制代码 代码如下: import java.io.File; import javax.xml.parsers.Document

  • Ruby程序中创建和解析XML文件的方法

    使用builder创建XML builder安装方法: gem install builder require 'builder' x = Builder::XmlMarkup.new(:target => $stdout, :indent => 1) #":target =>$stdout"参数:指示输出内 容将被写向标准输出控制台 #":indent =>1"参数:XML输出形式将被缩 进一个空格字符x.instruct! :xml, :

随机推荐