一场因为想偷懒引发的那些事——结构体的一些事

问题

如果有这么一段代码

     struct S
        {
            public int V1;
        }

        class A
        {
            public S SS{get;set;}          
        }

        static void Main(string[] args)
        {
            var a = new A();
            a.SS.V1 = 23333;
        }

这时候VS就会提示:无法修改SS的返回值,因为不是变量。
在这里插入图片描述

可能到这里大部分人,都会知道 a.SS 这个其实在返回的实际是在stack 上的一个拷贝,于是在修改a.SS.V1的时候修改的是这个拷贝里的 V1 的值,而实际a这个示例中的值并没被修改。(关于C#中值类型复制拷贝,这里就先不说了)


如果到这里关于上面那个错误提示的原因算是知道了,但是怎么证明呢?

于是,这就引发下面的内容


证明

我们先来修改一下代码

        unsafe class A
        {
            S s1;
            public S SS
            {
                get
                {
                    return s1;
                }
                set
                {
                    s1 = value;
                }
            }

            public IntPtr GetPsAddr()
            {
                fixed(int* p=&s1.V1)
                {
                    return new IntPtr(p);
                }             
                              
            }
        }

我们都知道 {get;set} 其实是一个语法糖,这次把这个语法糖展开成一个比较原始的写法,然后在A这个类内加一个方法,获取当前对象实例中V1的内存地址返回。

然后呢, Main这里这么小改一下:

     
        static void Main(string[] args)
        {
            var a = new A();
            var c=a.GetPsAddr().ToInt64();
            long b =(long)&a.SS.V1;
           
            Console.WriteLine($"c:{c:x}");
            Console.WriteLine($"b:{b:x}");
        }
            

于是乎,叮咚~ 编译器就又来报错了:
错误 CS1612 无法修改“Program.A.SS”的返回值,因为它不是变量

原因嘛当然是和上述的一样咯🙂

都到这里了,当然不能放弃,召唤出神器:


Dnspy


找到 /* 0x00000649 7C39000004 */ IL_001D: ldfld int32 TestThings.Program/S::V1

在这里插入图片描述

修改为 /* 0x00000649 7C39000004 */ IL_001D: ldflda int32 TestThings.Program/S::V1

在这里插入图片描述

ldfldldflda 不同在于 参考MSDN


ldfld: 查找对象中其引用当前位于计算堆栈的字段的值。


ldflda: 查找对象中其引用当前位于计算堆栈的字段的地址。

一顿操作,编译、运行,显示结果:

在这里插入图片描述

证明过程结束。

End

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Microsoft Speech SDK是微软公司开发的语音识别和语音合成软件开发工具包。它提供了一系列API和工具,使开发人员能够轻松地将语音识别和语音合成功能集成到他们的应用程序中。该SDK支持多种语言和操作系统,包括Windows、Android和iOS等。它可以用于开发各种语音应用程序,如语音助手、语音识别输入、语音控制等。 ### 回答2: Microsoft Speech SDK 是 Microsoft 公司开发的一套语音技术开发工具包,主要用于帮助开发者添加语音识别、语音合成、音频输入及输出等功能。作为一套强大而全面的语音技术开发工具包,它可以极大地便捷开发者构建语音应用程序,例如语音识别软件、语音助手、语音导航、语音翻译、语音评测等。 在语音识别方面,Microsoft Speech SDK 支持多种语言和语音模型,包括英语、中文、法语、西班牙语等。开发者可以通过简单的 API 调用实现对语音的识别,并可以通过调整配置文件来优化识别效果。在语音合成方面,Microsoft Speech SDK 同样支持多种语言,可以实现将文本转换成语音的功能。 作为一套全面的语音技术开发工具包,Microsoft Speech SDK 不仅支持语音识别和语音合成,还支持音频输入和输出,例如录音和播放音频,可以支持麦克风、音频文件等多种方式。同时,在语音评测方面,也提供了多种评测模型和算法,可以对说话人的语音进行分析,判断语音的准确性、流畅度等方面。 总之,Microsoft Speech SDK 是一套极为强大和全面的语音技术开发工具包,可以帮助开发者轻松地构建语音应用,减少了开发者在语音处理方面的复杂度和工作量,提高了语音应用程序开发的效率和可靠性。 ### 回答3: Microsoft Speech SDK是Microsoft提供的一套用于语音识别和合成的开发工具包,可帮助开发人员将语音技术集成到应用程序中,使应用程序具有语音识别和合成的功能。虽然Microsoft Speech SDK已被微软官方宣布停止维护和更新,但是它仍然是很多语音开发人员的首选工具之一。 Microsoft Speech SDK提供了各种API和库,可以支持多种编程语言和平台,例如,C++, C#, VB.NET,甚至还支持早期版本的ASP.NET。开发人员可以选择多种语言模型和语音引擎,以适应不同的语音应用场景。此外,SDK还提供了一些测试工具和示例代码,供开发人员参考和学习。 使用Microsoft Speech SDK可以实现自然语言的语音识别和语音合成技术,从而能够更好地实现人机交互,提高应用程序的易用性和用户体验。比如,通过语音识别技术,用户可以直接使用语音来操作程序,而无需使用鼠标和键盘,这大大提高了操作的效率。而通过语音合成技术,应用程序可以将文字转换为语音输出,从而帮助听障人士更好地使用应用程序。 除此之外,Microsoft Speech SDK在语音转录和实时语音转录等领域也有广泛的应用。例如,语音转录可以将语音直接转换为文本,应用于语音翻译、语音输入等场景。实时语音转录可以将多个说话者的语音同时转换为文本,应用于多人会议记录等场景。 总之,Microsoft Speech SDK是一套优秀的语音开发工具包,可以大大简化语音应用程序的开发过程,提高应用程序的交互性和可用性,使开发者能够更好地实现创新的语音应用程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值