C# 索引器与数组是怎么传递的?

发布于 2022-09-02 10:26:01 字数 999 浏览 14 评论 0

public class IndexerClass

{
    private string[] name = new string[3];

    //索引器必须以this关键字定义,其实这个this就是类实例化之后的对象
    public string this[int index]//    这里的index是代表数组name的下标吗???
    {
        //实现索引器的get方法
        get
        {
            if (index < 3)
            {
                return name[index];//   这里的name[index]代表的什么???
            }
            return null;
        }

        //实现索引器的set方法
        set
        {
            if (index < 3)
            {
                name[index] = value;
            }
        }
    }
}
public class Test
{
    static void Main()
    {
        //索引器的使用
        IndexerClass Indexer = new IndexerClass();
        //“=”号右边对索引器赋值,其实就是调用其set方法
        Indexer[0] = "张三";
        Indexer[1] = "李四";
        Indexer[2] = "王五";
        //输出索引器的值,其实就是调用其get方法
        Console.WriteLine(Indexer[0]);//张三
        Console.WriteLine(Indexer[1]);//李四
        Console.WriteLine(Indexer[2]);
        Console.ReadKey();
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

英雄似剑 2022-09-09 10:26:01

我写了段代码:

    int[] arr = new int[8];
    arr[0] = 1;
    Console.WriteLine(arr[0]);
    List<int> list = new List<int>(arr);
    list[0] = 1;
    Console.WriteLine(list[0]);

这是拿refelctor的逆向结果(对应的c#源码是我手动补上的):

.entrypoint
    .maxstack 3
    .locals init (
        [0] int32[] arr,
        [1] class [mscorlib]System.Collections.Generic.List`1<int32> list)
    L_0000: nop 
    // int[] arr = new int[8];
    L_0001: ldc.i4.8 
    L_0002: newarr int32
    L_0007: stloc.0 
    // arr[0] = 1;
    L_0008: ldloc.0 
    L_0009: ldc.i4.0 
    L_000a: ldc.i4.1 
    L_000b: stelem.i4 
    // Console.WriteLine(arr[0]);
    L_000c: ldloc.0 
    L_000d: ldc.i4.0 
    L_000e: ldelem.i4 
    L_000f: call void [mscorlib]System.Console::WriteLine(int32)
    L_0014: nop 
    // List<int> list = new List<int>(arr);
    L_0015: ldloc.0 
    L_0016: newobj instance void [mscorlib]System.Collections.Generic.List`1<int32>::.ctor(class [mscorlib]System.Collections.Generic.IEnumerable`1<!0>)
    L_001b: stloc.1 
    // list[0] = 1;
    L_001c: ldloc.1 
    L_001d: ldc.i4.0 
    L_001e: ldc.i4.1 
    L_001f: callvirt instance void [mscorlib]System.Collections.Generic.List`1<int32>::set_Item(int32, !0)
    L_0024: nop 
    // Console.WriteLine(list[0]);
    L_0025: ldloc.1 
    L_0026: ldc.i4.0 
    L_0027: callvirt instance !0 [mscorlib]System.Collections.Generic.List`1<int32>::get_Item(int32)
    L_002c: call void [mscorlib]System.Console::WriteLine(int32)
    L_0031: nop 
    L_0032: ret 

索引器又叫做“索引属性”,也是属性的一种。而属性最终都要编译成普通方法的形式。反映在msil上面就是callvirt实例方法调用,set_Item(int32, !0)get_Item(int32)

数组的下标操作应该是msil的特化指令,可以看到上图中有newarrstelemldelem指令。

自己可以拿个reflector看编译后的msil。

寄居者 2022-09-09 10:26:01
public string this[int index]//    这里的index是调用Indexer[0]的时候传进来的0


return name[index];//   这里的index是调用Indexer[0]的时候传进来的0
拥抱没勇气 2022-09-09 10:26:01

//个人理解,如有错误请明示!

class class1
{
    private int[] number;
    
    public int this[int index]
    {
    get {return number[index]};
    set{number[index] = value};
    }
}

//.....

class1 c1 = new class1();
c1[0] = 65535;//这里用到的就是索引器。
c1[1] = 23333;//其实就是以这种- 实例名[0] -方式访问class1类的私有成员->number数组。
//看起来和字段很像不是吗?

//.....
//ps:自学来的,可能有错误。而且是自己的理解,如有错误请不吝指导。
//pps:首答!(学知乎上的)
//检查了一遍回答之后发现有点答不对题。。。每太理解传递的意思
//可以理解为 c1[0] 与类的私有成员 number[0]是对应吧

娇女薄笑 2022-09-09 10:26:01

简单的说,索引器是一种数据存取的方式,就是以方括号的方式获取/设置类似于集合的成员值这样的一种方式。索引器不一定要与内部数据对应,比如

class HexIndexer {
    public string this[int n] {
        get { return n.ToString("X2"); }
    }
}

var hex = new HexIndexer();
string s = hex[10];    // "0A"

当然,也不一定非得是 int 参数,比如

public class StringIndexer {
    public int this[string v] {
        get { return v?.Length ?? -1; }
    }
}

var s = new StringIndexer();
int x = s["hello"];     // 5
int y = s[null];        // -1

甚至,索引也可以是多维的(不止一个参数),比如

class CharIndexer {
    public char this[string s, int i] {
        get { return s[i]; }
    }
}

var c = new CharIndexer();
char x = c["james", 3];     // 'e'

当然上面的例子都只实现了 get,忽略了 set,要实现 set 也类似,只是因为我这些实际都没有什么实际意义,所以就懒得写 set 了。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文