首页 > 编程语言 >C# get、set 说明

C# get、set 说明

时间:2024-02-16 13:33:39浏览次数:23  
标签:set name get C# age value public

一、get、set 的基本简介  

在面向对象编程(OOP)中,是不允许外界直接对类的成员变量直接访问的,既然不能访问,那定义这些成员变量还有什么意义呢?所以C#中就要用set和get方法来访问私有成员变量,它们相当于外界访问对象的一个通道,一个“接口”。先来看一段代码:

复制代码 复制代码
class Employee
  {
        private string name;
        private byte age;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        public byte Age
        {
            get { return age; }
            set { age = value; }
        }
  }
复制代码 复制代码

  代码中定义了两个私有变量name和age,当我们不想让外界随意访问该私有变量时,可以使用属性来访问,语法为:

public <返回类型(要与被访问变量的类型相同)> <属性名(不能与被访问变量同名)>
  {
        get{ return <被访问变量>;}
        set{ <被访问变量> = value;}
  }

 

  当我们使用属性来访问私有成员变量时就会调用里面的get方法,当我们要修改该变量时就会调用set方法,当然在定义的时候可以只定义一个get方法或只定义一个set方法。如果只定义get方法,那么这个相应变量就是“只读”的;如果只定义set方法,那么相应变量就是“只写”的。

  既然外界可以通过set和get访问类内私有成员,那为什么不直接把它定义成共有,直接供外界访问呢?拿上面的Employee类来说明:

复制代码 复制代码
class Employee
    {
        private string name;
        private byte age;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        //****修改后****↓↓↓↓↓↓↓↓
        public byte Age
        {
            get { return age; }  
            set
            {                
                if (value > 10 && value<=100)   //一般在公司雇员的年龄都在10到100岁之间
                age = value;   
            }
        }
        //****修改后****↑↑↑↑↑↑↑↑
    }
复制代码 复制代码

 

  上例中,set就像一位门卫大叔一样,只有好人才能进来。可以通过属性来控制对员变量的读写,防止对成员变量的非法赋值等。

  再举个小例子,以下是个温度计的类:

复制代码 复制代码
class Thermometer
    {
        private double temperature;
        public Thermometer(double temperature)  //构造函数
        {
            this.temperature = temperature;
        }
        public double Temperature
        {
            get { return temperature; }
            set { temperature = value; }
        }
    }
复制代码 复制代码

 

  假设这里的温度单位表示的是摄氏度(℃),如果在需求分析阶段误解了客户的原始意愿或者客户在日后变更了需求,需要把系统中所有表示温度的变量temperature都用来表示开尔文温度(K)。那么不必动系统中成百上千个Temperature属性,只需在get和set函数中稍微修改一下代码即可:

  

复制代码 复制代码
class Thermometer
    {
        private double temperature;
        public Thermometer(double temperature)  //构造函数
        {
            this.temperature = temperature;
        }
        public double Temperature
        {
            //****修改后****↓↓↓↓↓↓↓↓
            get { return temperature-273.15; }
            set { temperature = value+273.15; }
            //****修改后****↑↑↑↑↑↑↑↑
        }
    }
复制代码 复制代码

 

建一个控制台应用程序来测试一下,主函数为:

 

复制代码 复制代码
class Test
    {
        static void Main(string[] args)
        {
            Thermometer a = new Thermometer(40);
            Console.WriteLine(a.Temperature);
        }
    }
复制代码 复制代码

上面代码中用构造函数给温度设的初值为40度,代码修改前运行结果为“40”,代码修改后运行结果为“-233.15”。

 

_____________________________________________________________________________________________________________________________________________________________

二、实例说明

1、person类举例如下:

复制代码 复制代码
public class person1
{
    public string name;
}

public class person2
{
public string Name{set;get;}
}

复制代码 复制代码

 第一个类型的name属性未封装,其name属性直接通过public关键字暴露给系统中的其他类了。而第二个类型的name属性通过get和set关键字进行了封装,get和set分别对应的是可读和可写。由于其除了可读可写外,没有其它的条件限制操作,所以相当于如下代码:

 

复制代码 复制代码
// 字段:一般为私有的,不对外开放
private string name;

// 属性:一般为公有的,作为外部访问对应字段的一个接口
public string Name
{
get { return name; } //相当于通过Name来返回name的值
  set { name = value; } //通过Name来设置name的值
}

复制代码 复制代码

* 以上的不同写法的区别:

 

  • 当实例化第一个“人 -person1-”这个类时,系统在分配内存空间时对name属性直接分配内存,之后对name属性的操作也是直接操作内存中name属性所在的这个块
  • 当实例化第二个“人”类型时,系统会先分配一个叫name的private私有的内存空间,之后的读与写的操作都是通过Name这个public的类似于指针的东西来关联name进行,以此达到封装的目的,并且通过get和set关键字也可以控制可读还是可写。建议用后者。

 

2、至于get和set的作用,除了控制读写之外还有逻辑、条件判断的作用。例如当给Name赋值的时候想要先进行一些逻辑判断,就可以这样:

复制代码 复制代码
private string name;
public string Name
{
    get { return name; }
    set
    {
     name = String.IsNullOrEmpty(value) ? "空" : value;
    }
}
复制代码 复制代码

 

3、再举例说明下

复制代码 复制代码
class Test
    {
        private int age;
        public int Age
        {
            get { return age; }
            set { if (value < 0 || value > 200)
                {
                    Console.WriteLine("无效的赋值,年龄必须在0——200之间");
                }
                else
                {
                    age = value;
                }
        }
    }
}</pre>
复制代码 复制代码

 

C#中get、set用法中,类的set和get成员是外部程序访问类内部属性的唯一方法,就像你去银行取钱,你不能直接从银行的保险柜里拿钱,而是银行营业人员把钱取出来给你的。 
  属性在调用者看来就像一个普通的变量,但作为类的设计者,你可以利用属性来隐藏你类中的一些字段,使外界只能通过属性来访问你的字段,你可以通过属性来限制外界对你的字段的存取,就利用get、set。如果想让用户随意存取你的字段,那么就实现get、set;如果只想让用户读取字段,就只实现get;若只想让用户写字段就只实现set。同时还可以在set和get中对用户传递的值进行一些验证工作,以确保你的字段将含有正确的值。

 

 

复制代码 复制代码
private int a;
public int index
{
    get
    { return a; }
    set
    {
     If (value>0)
       a=value;
     else
       a=0;
    }
}
复制代码 复制代码

 

 4、可看出,get、set用法有如下特点:

  • 一则是隐藏组件或类内部的真是成员;
  • 二是用来建立约束的,比如,实现“有我没你”这种约束;
  • 三是用来响应属性变化事件,当属性变化是做某事,只要写在set方法里就行;

当想读出或写入属性的值时,存取标志限定了被实现的语句。用于读出属性的值的存取标志记为关键字get,而要修改属性的值的读写符标志记为set。

 

 

三、最新简化使用方法

对于只是限定读取和访问权限,而无复杂逻辑条件判断的,可以使用一些简化的方式。

1、原始写法

复制代码 复制代码
// 写法一
    class Test
    {
        private int age;
        public int Age
        {
            get { return age; }
            set { age = value; }
        }
    }

// 写法二
class Test
{
private int age;
public int Age
{
get => age;
set => age = value;
}
}

复制代码 复制代码

2、简化写法

复制代码 复制代码
    class Test
    {
        public int Age
        { get; set; }
    //或者直接省略
    public int Name;
}</pre>
复制代码 复制代码

 

 

文章转载自:http://blog.csdn.net/u013095889/article/details/52804360

标签:set,name,get,C#,age,value,public
From: https://www.cnblogs.com/QHMG/p/18017077

相关文章

  • HackTheBox - Drive
    #nmap--top-ports=100010.10.11.235StartingNmap7.94SVN(https://nmap.org)at2024-02-1511:10CSTNmapscanreportfordrive.htb(10.10.11.235)Hostisup(0.12slatency).Notshown:997closedtcpports(reset)PORTSTATESERVICE22/tcpop......
  • Codeforces Round 926 (Div. 2)(A~D)
    目录ABCDA输出最大值减最小值,或者排序算一下答案#include<bits/stdc++.h>#defineintlonglong#definerep(i,a,b)for(inti=(a);i<=(b);++i)#definefep(i,a,b)for(inti=(a);i>=(b);--i)#definepiipair<int,int>#definelllonglong#definedb......
  • Codeforces Round 926 (Div. 2) 题解
    比赛链接:https://codeforces.com/contest/1929官解链接:https://codeforces.com/blog/entry/125943出的很差的一场。推歌CF1929A.SashaandtheBeautifulArray题意任意排列数组\(a_{1..n}\),求\(\sum_{i=2}^n(a_i-a_{i-1})\)的最大值。题解见过最显然的A题,奠定了......
  • dotnet-cnblog tool 测试案例
    这是测试donet-cnblog工具是否能将正常的Typora图片转换为博客园格式测试1:本地图片导入测试2:QQ截图测试3:urlhttps://pics3.baidu.com/feed/9345d688d43f8794105499b2ead60ef819d53ad8.jpeg@f_auto?token=d70fe4868ac1356d70833be721199be3结论成功!!!随后整理出自己的实践......
  • [TileDB::Buffer] Error: Cannot read from buffer; End of buffer reached.
     001、问题: gatkDBI模块在sheep1号染色体(其他染色体同样的命令并没有报错;一共134sheep个体)调用GenotypeGVCFs命令call snps时出现如下报错: 002、问题原因itlookslikewearehittingthelimitsofzlibmemory-wise.(达到zlib库的内存上限?) 003、解决方法......
  • Semantic Kernel + 通义千问:借助 one-api 调用阿里云灵积 DashScope api
    one-api相当于是一个兼容OpenAIapi的api网关(针对api的反向代理),借助one-api可以通过已有的OpenAI客户端调用非OpenAI大模型的api,比如通义千问。DashScope是阿里云提供的模型服务灵积的英文名称,这里通过调用DashScopeapi使用通义千问qwen-max大模型。以容器......
  • CF1929
    A最大值-最小值B题意:在\(n\timesn\)的方阵中选择若干个方块,使得至少有\(k\)条对角线上有选择的方块。观察:如果选择第一行的\(n\)个,和最后一行的中间\(n-2\)个,可以覆盖\(4n-4\)条对角线,这其中每一个格子都恰好覆盖两条对角线。所以如果\(k\le4n-4\),输出\(\lce......
  • [NISACTF 2022]easyssrf
    先按照最简单的试试 那就试试/fl4g,需要使用file伪协议进行文件读取,然后得到新的提示 进入新的目录 直接构造路劲进行flag的读取 也可以利用别的伪协议url?file=php://filter/read=convert.base64-encode/resource=/flag  ......
  • docker的私有仓库harbor
    [root@localhost~]#mkdir-p/data/ssl [root@localhost~]#cd/data/ssl/ [root@localhostssl]#opensslreq-newkeyrsa:4096-nodes-sha256-keyoutca.key-x509-days365-outca.crtGeneratinga4096bitRSAprivatekey.................++.................
  • CentOS7 离线安装 Docker
    对于一些安全性要求比较高的项目,服务器一般都是内网,无法联网。如果直接在物理机或虚拟机上部署项目,一方面比较麻烦,另外风险也比较高,如果出现了一些问题,最坏的情况就是重置操作系统,然后重新部署,耗时费力。还是采用docker部署会比较方便,我们可以在外部可以联网的机器上把项目部署......