.NET 欢乐编程术之类型超级转换之术👍👍
准备工作:先确保 VS 版本大于 2017,且支持C# 7.0 语言版本。然后新建 .Net Core 项目,在 Nuget 包管理上引入微软霸霸官方包 System.Runtime.CompilerServices.Unsafe。此包提供了非常底层又符合 .Net CLR 的 API,包括操作指针,引用,内存的方法。
接下来我们就可以利用这个包,去获取一个字符串的内存信息,然后更改这个字符串的内容。众所周知,.Net 中的字符串是不可变的,C# 和 .Net 都极大的限制程序员不可修改字符串的内容,因为一旦修改了字符串的内容,将破环 CLR 的规则,使得程序变得不稳定。
首先我们定义一个与 String 类型字段结构完全一样的类型:
public sealed class MyString
{
/// <summary>
/// 字符串的长度。
/// </summary>
public int _stringLength; /// <summary>
/// 字符串第一个字符,它与后续的字符的内存是连续的。
/// </summary>
public char _firstChar;
}
然后我们定义一个字符串:
var str = "Dogwei 牛B!";
然后我们将这个字符串超级转换为 MyString 类型:
var myStr = System.Runtime.CompilerServices.Unsafe.As<MyString>(str);
现在我们可以修改字符串的内容了:
var str = "Dogwei 牛B!"; var myStr = System.Runtime.CompilerServices.Unsafe.As<MyString>(str); Unsafe.Add(ref myStr._firstChar, str.IndexOf('牛')) = 'S'; Console.WriteLine(str); // Output : Dogwei SB!
怎么样,是不是很有意思?我们再来试试修改字符串长度:
myStr._stringLength = ; Console.WriteLine(str); // Output : Dogwei myStr._stringLength = ; Console.WriteLine(str); // Dogwei SB! ??翽 鄈淭翽...
长度超过字符串本来的长度会输出一串乱码。
同样转换之后的方法也是可以执行的:
public class Demo
{
public static void Main()
{
var str = "Dogwei 牛B!"; var myStr = Unsafe.As<MyString>(str); myStr.SayHello();
}
}
public sealed class MyString
{
/// <summary>
/// 字符串的长度。
/// </summary>
public int _stringLength; /// <summary>
/// 字符串第一个字符,它与后续的字符的内存是连续的。
/// </summary>
public char _firstChar; public void SayHello()
{
var str = Unsafe.As<string>(this); var splits = str.Split(' '); var name = splits[]; var say = splits[]; Console.WriteLine($"Hello! my name is {name}, I am {say}.");
}
}
但是执行方法有一个必须要注意的地方,就是执行的方法必须是最终方法!(何为最终方法请查阅微软官方文档 System.Reflection.MethodInfo.IsFinal)。如果不是最终方法会怎么样呢?我们来试试:
同上例,Main 方法保持不变,修改 MyString 为如下:
public class MyString
{
/// <summary>
/// 字符串的长度。
/// </summary>
public int _stringLength; /// <summary>
/// 字符串第一个字符,它与后续的字符的内存是连续的。
/// </summary>
public char _firstChar; public virtual void SayHello()
{
var str = Unsafe.As<string>(this); var splits = str.Split(' '); var name = splits[]; var say = splits[]; Console.WriteLine($"Hello! my name is {name}, I am {say}.");
}
}
执行程序后什么也没发生,既没执行,也没报错:
到这里相信大家也对类型强转超级之术有一点理解,但是这个“巫术”有一些限制:
1:不能转换为值类型!
2:转换之后必须显式定义类型,否则将无意义。
下一章我们将讲超级转换之术二代!可以转换任何对象,且是实际意义转换。
.NET 欢乐编程术之类型超级转换之术👍👍的更多相关文章
- C#高级编程笔记 2016年10月8日运算符和类型强制转换
1.checked和unchecked 运算符 C#提供了checked 和uncheckde 运算符.如果把一个代码块标记为checked, CLR就会执行溢出检查,如果发生溢出,就抛出overfl ...
- C#高级编程9-第7章 运算符和类型强制转换
运算符和类型强制转换 1.运算符 运算符的简化操作 条件运算符: if-else的简化操作,也称三元运算符.如果条件为真,返回一个值,为假返回另外一个值. condition?true_value:f ...
- C#高级编程 (第六版) 学习 第六章:运算符和类型强制转换
第六章 运算符和类型强制转换 1,运算符 类别 运算符 算术运算符 + - * / % 逻辑运算符 & | ^ ~ && || ! 字符串连接运算符 + 增量和减量运算符 ++ ...
- 【读书笔记】C#高级编程 第七章 运算符和类型强制转换
(一)运算符 类别 运算符 算术运算符 + - * / % 逻辑运算符 & | ^ ~ && || ! 字符串连接运算符 + 增量和减量运算符 ++ -- 移位运算符 < ...
- 【转】java中byte数组与int类型的转换(两种方式)----不错
原文网址:http://blog.csdn.net/piaojun_pj/article/details/5903009 java中byte数组与int类型的转换,在网络编程中这个算法是最基本的算法, ...
- C语言指针类型 强制转换
关于C语言指针类型 强制转换 引用一篇文章: C语言中,任何一个变量都必须占有一个地址,而这个地址空间内的0-1代码就是这个变量的值.不同的数据类型占有的空间大小不一,但是他们都必须有个地址,而这个 ...
- C++四种类型的转换
在C/C++使用的语言 (type) value(您还可以使用type(value))对于显式类型转换,经常提到投.转换程序猿的精度等完全掌握手,一个传统投往往是过度使用.成为C++要根源. 为了降低 ...
- 《Python核心编程》数字类型
1.数字类型简单介绍 Python中数字类型包含:整型.长整型.布尔型.双精度浮点型.十进制浮点型.复数.这些数字类型都是不可变类型.也就是说,改变了数字的值会生成新的对象. 在Python中删除数字 ...
- FILETIME类型到LARGE_INTEGER类型的转换
核心编程第5版 245页到247页的讲到SetWaitableTimer函数的使用 其中提到 FILETIME类型到LARGE_INTEGER类型的转换问题,如下代码 //我们声明的局部变量 HAND ...
随机推荐
- <iOS小技巧> 返回上级目录操作Goback()方法
Goback()方法功能:返回上一级界面,通过判断 popViewControllerAnimated 类型是否为空,来判断是present还是pop出来,然后直接做了releaseSelf操作: - ...
- 【canvas】blackboard 黑板
本来想的挺复杂实际操作了一下15分钟完成了,挺简单的. 预览地址:http://dtdxrk.github.io/game/blackboard/index.html 分享一下思路: 1.创建画布 2 ...
- 核心思想:想清楚自己创业的目的(如果你没有自信提供一种更好的产品或服务,那就别做了,比如IM 电商 搜索)
这个时代对于学 IT 的人来说是幸运的.一个普通的程序员可以相对轻易地找到工作,可以轻易拿到比其他行业高得多的工资,甚至自己创建世界级的企业亦非空想.马云.马化腾等企业家的成功,似乎时刻提醒人们:即便 ...
- 30+ 强大的Buddypress主题–开始您的社区站点吧
BuddyPress起源于2008年,当时设计者设想添加社交网络功能到WordPress多用户版本中.第一个正式稳定版本的发布是在2009年的5月.自从那时起.BuddyPress开始快速的成长和演变 ...
- 32个Python爬虫项目让你一次吃到撑
整理了32个Python爬虫项目.整理的原因是,爬虫入门简单快速,也非常适合新入门的小伙伴培养信心.所有链接指向GitHub,祝大家玩的愉快~O(∩_∩)O WechatSogou [1]- 微信公众 ...
- 基于jsp技术的校园二手交易网站
[项目介绍]基于jsp的校园二手商品交易网站系统使用jsp技术进行开发,项目主要实现了一整套的校园二手交易逻辑, 主要功能如下(包括但不限于,只列出主要功能): 管理员模块 |-----用户管理 ...
- Fabric1.4源码解析: 链码容器启动过程
想写点东西记录一下最近看的一些Fabric源码,本文使用的是fabric1.4的版本,所以对于其他版本的fabric,内容可能会有所不同. 本文想针对Fabric中链码容器的启动过程进行源码的解析.这 ...
- TCP/IP协议栈---网络基础篇(3)
TCP/IP协议栈 在网络中实际使用的是TCP/IP,OSI是参考模型. TCP/IP协议栈 – 是由一组不同功能的协议组合在一起构成的协议栈 – 利用一组协议完成OSI所实现的功能 应用层协议 传输 ...
- CRISP-DM--数据挖掘标准流程
CRISP-DM--数据挖掘标准流程 在1996年的时候,SPSS,戴姆勒-克莱斯勒和NCR公司发起共同成立了一个兴趣小组,目的是为了建立数据挖掘方法和过程的标准.并在1999年正式提炼出了CRISP ...
- 巧妙解决element-ui下拉框选项过多的问题
1. 场景描述 不知道你有没有这样的经历,下拉框的选项很多,上万个选项甚至更多,这个时候如果全部把数据放到下拉框中渲染出来,浏览器会卡死,体验会特别不好 用人会说element-ui的select有一 ...