首页 > 编程语言 >C#学习笔记 -- 对象初始化语句、索引器、访问器的修饰符

C#学习笔记 -- 对象初始化语句、索引器、访问器的修饰符

时间:2023-05-21 12:44:06浏览次数:38  
标签:index set get C# 修饰符 访问 -- 索引 public

1、对象初始化语句

扩展语法

  • 有如下两种扩展语法,

    • 第一种当类中没有声明构造器或者声明了无参构造器才能用

    • 第二种当类中声明了有参构造器才能用

new ExampleClass {FieldOrProp = InitProp, FieldOrProp = InitProp, ...};
new ExampleClass(ArgList) {FieldOrProp = InitProp, FieldOrProp = InitProp, ...};

对于一个名为Point、有两个公有整型字段X、Y的类, 可以使用扩展语法如下表示

new Point {X = 5, Y = 6};
注意
  1. 创建对象的代码必须能够访问要初始化的字段和属性, 例如上例中X、Y是公有的

  2. 初始化发生在构造方法执行之后, 因此构造方法中设置的值可能会在之后对象初始化中重置为相同或不同的值

  3. 接第二条, 即使用有参构造器也会重置为扩展语法中的值

例子

class Program713
{
    public int X = 1;
    public int Y = 2;
​
    public Program713(int x, int y)
    {
        X = x;
        Y = y;
    }
​
    public Program713()
    {
    }
}
static void Main(sting[] args)
{
    Program713 program713Cons = new Program713();
    Program713 program713Args = new Program713(3, 4) { X = 5, Y = 6 };
    Program713 program713 = new Program713 { X = 7, Y = 8 };
    Console.WriteLine($"构造函数构造出的实例: X = {program713Cons.X}, Y = {program713Cons.Y}"); //1 2
    Console.WriteLine($"有参对象初始化语句初始的类: X = {program713Args.X}, Y = {program713Args.Y}"); //5 6
    Console.WriteLine($"无参对象初始化语句初始的类: X = {program713.X}, Y = {program713.Y}"); //7 8
}

2、索引器

(1)什么是索引器

索引器是一组get和set访问器, 与属性类似

string this [int index]
{
    set {}
    get {}
}

(2)索引器和属性

  • 和属性一样, 索引器不用分配内存来存储

  • 索引器和属性都主要被用来访问器他数据成员, 他们与这些成员关联, 并为他们提供获取和设置访问

    • 属性通常表示单个数据成员

    • 索引器通常表示多个数据成员

  • 可以认为索引器是为类的多个数据成员提供get的set访问的属性

  • 通过提供索引器, 可以在许多可能的数据成员中进行选择

  • 索引本身可以是任何类型, 而不仅仅是数值类型

注意
  1. 与属性一样, 索引器可以只有一个访问器, 也可以两个都有

  2. 索引器总是实例成员, 因此不能被声明为静态

  3. 与属性一样, 实现get和set访问器的代码不一定要关联到某个字段或者属性, 这段代码可以做任何事情也可以什么都不做, 只要get访问器返回某个指定的类型即可

(3)声明索引器

  • 索引器没有名称, 在名称位置是关键字this

  • 参数列表在方括号中间

  • 参数列表必须至少声明一个参数

ReturnType this [Type arg, ...]
{
    set {}
    get {}
}

(4)索引器的set访问器

当索引器被用于赋值时, set访问器被调用, 并接受两项数据

  • 一个名为value的隐式参数, 其中持有要保存的数据

  • 一个或更多索引参数, 表示数据应该保存到哪里

emp[索引参数] = 值;

在访问器中的代码必须检查索引参数, 以确定数据应该存往何处, 然后保存他

Type this [Args]
{
    set{}
    get{}
}
void set(Args, Type value)
{
    ...
}

上方的代码块表示set访问器的语义

  • 它的返回类型为void

  • 他使用的参数列表和索引器声明中相同

  • 有一个value隐式参数, 类型和索引器类型相同

(5)索引器的get访问器

当使用索引器获取值时, 可以通过一个或多个索引参数调用get访问器, 索引参数指示获取那个值

string s = emp[索引参数]
Type this [Args]
{
    set{}
    get{}
}
Type get (Args)
{
    return vars;
}

上方的代码块表示get访问器的语义

  • 他使用的参数列表和索引器声明中相同

  • 返回值类型和索引器类型相同

(6)索引器隐式调用、自动调用

  • 索引器不能显示调用setter和getter

  • 取而代之, 当索引器在表达式中取值的时候, 将自动调用get访问器.

  • 当使用赋值语句对索引器赋值时, 自动调用set访问器

  • 在调用索引器时, 要在方括号内提供参数

(7)索引器例子

例子一: 为Emplyee声明索引器
  • 索引器需要读写string类型的值, 所以string必须声明为索引器的类型, 他必须声明为public, 以便从类的外部访问

  • 3个字段被随意的索引为整数0~2, 所以本例中index形参必须为int

  • 在setter中, 代码确定索引指的是那个字段, 并把隐式变量value的值赋值给他

  • 在getter中, 代码确定索引的是哪个字段, 并返回该字段的值

class Employee
{
    public string LastName;
    public string FirstName;
    public string CityOfBirth;
​
    public string this [int index]
    {
        set 
        {
            switch (index)
            {
                case 0: LastName = value;
                    break;
​
                case 1:
                    FirstName = value;
                    break;
​
                case 2:
                    CityOfBirth = value;
                    break;
                default:
                    throw new ArgumentOutOfRangeException("index");
            }
        }
        get 
        {
            switch (index)
            {
                case 0:
                    return LastName;
                case 1:
                    return FirstName;
                case 2:
                    return CityOfBirth;
                default:
                    throw new ArgumentOutOfRangeException("index");
            }
        }
    }
}
例子二
class Class1
{
    int Temp0;
    int Temp1;
    public int this[int index]
    {
        set 
        {
            if (index == 0)
            {
                Temp0 = value;
            }
            else if (index ==1)
            {
                Temp1 = value;
            }
            else
            {
                throw new ArgumentOutOfRangeException("index");
            }
        }
​
        get 
        {
            if (index > 1 || index < 0)
            {
                throw new ArgumentOutOfRangeException("index");
            }
            return index == 0 ? Temp0 : Temp1;
        }
    }
}
static void Main(string[] args)
{
    Class1 class1 = new Class1();
    Console.WriteLine($"调用索引setter前 调用索引getter Value = {class1[0]}, {class1[1]}");
    class1[0] = 10;
    class1[1] = 25;
    Console.WriteLine($"调用索引setter后 调用索引getter Value = {class1[0]}, {class1[1]}");
}

(9)索引器重载

  • 只要索引器的参数列表不同, 类可以拥有任意多个索引器, 构成索引器重载

  • 索引器类型不同是不够的, 因为所有索引器都有相同的名称this, 返回值类型不同不构成重载

class Progrom717_9
{
    public string this[int index]
    {
        set { }
        get { }
    }
​
    public string this[int index1, int index2]
    {
        set { }
        get { }
    }
​
    public int this[float index]
    {
        set { }
        get { }
    }
}

3、访问器的修饰符

  • 默认情况下, 成员的两个访问器的访问级别和成员自身相同

    • 即如果一个属性的访问级别是public, 那么它的访问器也是public

  • 可以将两个访问器分配不同访问级别, 如下方例子

  • 尽管可以从类的外部读取属性, 但是只能在类的内部设置他, 下方例子在构造函数中设置

class Person
{
    //属性:名字, setter访问器是私有的, 在构造函数中设置属性
    public string Name { private set; get; }
​
    public Person(string name)
    {
        Name = name;
    }
}
static void Main(string[] args)
{
    Person person = new Person("Lyu King");
    Console.WriteLine($"这个人的名字叫: {person.Name}");
}
注意

访问器的访问修饰符有如下几个限制

  • 仅当成员(属性或索引器)既有getter也有setter时, 其访问器才能有访问修饰符

  • 虽然两个访问器都必须出现, 但他们中只能有一个访问修饰符

  • 访问器的访问修饰符限制必须比成员的访问级别更严格

    • 比如一个属性访问级别是public, 那么任何一个访问器的级别必须是如下图(访问器级别显示层次) public之下的层级

标签:index,set,get,C#,修饰符,访问,--,索引,public
From: https://www.cnblogs.com/phonk/p/17418463.html

相关文章

  • 主流原型设计工具介绍
    原型设计是将想法转变为设计过程中十分重要的环节,而原型工具允许我们在设计过程中快速创建交互式模型,模拟应用程序的功能和流程。当下原型工具种类繁多,下面将介绍几种主流的原型设计工具及其使用。 一.AxureRP AxureRP是美国AxureSoftwareSolution公司旗舰产品,是......
  • MFC视图切换大全总结
    单纯视图之间的切换单文档多视图切换是我在学习MFC中遇到的一个老大难问题,在今天总算是一一破解了。我觉得视图切换分为三个等级,第一是在未切分窗格的情况下切换视图类;第二是在分割窗格的一个窗格内实行视图切换;第三是在分割窗格和未分割之间的切换和视图切换。在MFC创建SDI的伊......
  • DTact-mini
    热风枪变形亚克力rbfi_x=Rbf(corr_array[:,0],corr_array[:,1],init_array[:,0],function='cubic')rbfi_y=Rbf(corr_array[:,0],corr_array[:,1],init_array[:,1],function='cubic')x_index=rbfi_x(x_mes......
  • Python3.8多进程之共享内存
    转载:Python3.8多进程之共享内存-知乎(zhihu.com)最近发了个宏愿想写一个做企业金融研究的Python框架。拖出Python一看已经更新到了3.8,于是就发现了Python3.8里新出现的模块:multiprocessing.shared_memory。随手写了个测试。生成一个240MB大小的pandas.DataFrame,然后转换成nu......
  • Jmeter函数助手18-machineIP
    machineIP函数用于获取本地IP地址。存储结果的变量名(可选) 1、本地ip可以在cmd运行界面输入命令“ipconfig”查看,Jmeter则使用函数获取${__machineIP()} ......
  • easyExcel读写入csv文件
    写入:Filefile=newFile(System.getProperty("java.io.tmpdir")+File.separator+"aa.csv");ExcelWriterexcelWriter=EasyExcelFactory.write(file).excelType(ExcelTypeEnum.CSV).charset(Charset.forName("GBK"))......
  • 04-多路选择器
    1.多路选择器组合逻辑是Verilog设计中的一个重要组成部分,从电路本质上讲,组合逻辑电路的特点是输出信号只是当前时刻输入信号的函数,与其他时刻的输入状态无关,无存储电路,也没有反馈电路组合逻辑电路输出信号的电平变化仅仅与输入信号的电平变化有关,不涉及信号跳变沿的处理......
  • 图像二值化
    阈值效果示例颜色通道滤色#00ffff白GB差值#ff0000白仅R正片叠底#00ffff黑仅R正片叠底#ff0000黑GB......
  • Off-Policy Deep Reinforcement Learning without Exploration
    发表时间:2019(ICML2019)文章要点:这篇文章想说在offlineRL的setting下,由于外推误差(extrapolationerrors)的原因,标准的off-policy算法比如DQN,DDPG之类的,如果数据的分布和当前policy的分布差距很大的话,那就很难从data里学到好的policy。然后文章提出了batch-constrainedreinforceme......
  • AtCoder Regular Contest 130 E Increasing Minimum
    这题太神仙了吧!感觉还不是很懂,但是尽力理一下思路。设\(t_x\)为最大的\(j\)使得\(i_j=x\),不存在则\(t_x=0\)。设\(1\simn\)的数按照\(t\)从小到大排序后是\(p_1,p_2,...,p_n\),设\(q_i\)为\(i\)在\(p\)中的排名,即\(q_{p_i}=i\)。发现正着不好考虑,......