c# - 复制字符串并更改其值不会更改原始值
问题描述
public string gametext;
public Gameplay()
{
InitializeComponent();
gametext = tbGameplayMessage.Text;
}
private void button_Click(object sender, EventArgs e)
{
gametext += "Write textbox \r\n";
}
private void button2_Click(object sender, EventArgs e)
{
gametext += "Write textbox \r\n";
}
这是我的代码,我正在尝试做的是每次单击按钮时更新文本框,并在单击按钮2 时写入更多行。我的文本框已经启用了多行。当我运行我的代码时,文本框没有任何反应:(
解决方案
解决您的问题的方法是Text
直接更新属性:
private void button_Click(object sender, EventArgs e)
{
tbGameplayMessage.Text+= "Write textbox \r\n";
}
那么让我们来看看发生了什么。
Text
是一个string
属性:
tbGameplayMessage.Text
string
是一个引用类型,我们知道如果我们复制一个引用,我们有 2 个变量指向内存中的相同位置。
让我们看看它的实际效果:
// create a string
var a = "test1";
// copy a to b
var b = a;
// this is just a way of getting our strings position in memory
fixed (char* pa = a,pb = b)
{
Console.WriteLine($"a : {a} @ {(uint)pa}");
Console.WriteLine($"b : {b} @ {(uint)pb}");
}
输出
a : test1 @ 51748
b : test1 @ 51748
如您所见,a
和b
都指向同一个内存位置 51748
。好的,到目前为止一切都很好
但是请注意当我们分配一个新字符串 ( "test2"
)时会发生什么a
a = "test2";
fixed (char* pa = a, pb = b)
{
Console.WriteLine($"a : {a} @ {(uint)pa}");
Console.WriteLine($"b : {b} @ {(uint)pb}");
}
输出
a : test2 @ 51876
b : test1 @ 51748
通知b
中仍然包含原来的string
test1
和指向同一个位置,但是a
已经取了我们新的string
,并且是指向不同的位置。
这是因为string
它是一个引用类型,而您的变量只持有一个指向实际内存位置的指针(便利贴)。
当你为一个变量分配另一个引用时,你给它一个新的位置来指向内存
这就是为什么当你改变时你不能分配你 tbGameplayMessage.Text
并gametext
期望tbGameplayMessage.Text
改变的原因gametext
gametext = tbGameplayMessage.Text;
以上是将引用复制到保存在Text
.
当您提供gametext
新参考时,Text
仍然有旧参考(它不会改变)。
让我们更好地了解这一点:
var a = "test";
for (int i = 0; i < 5; i++)
{
a += i;
fixed (char* pa = a)
{
Console.WriteLine($"a : {a} @ {(uint) pa}");
}
}
输出:
a : test10 @ 67684
a : test101 @ 67812
a : test1012 @ 67940
a : test10123 @ 68068
a : test101234 @ 68196
每次我们触摸字符串时,它都会指向不同的位置。
现在有一个额外的事实,如果我们分配"test1"
回去a
看看会发生什么:
a = "test1";
fixed (char* pa = a, pb = b)
{
Console.WriteLine($"a : {a} @ {(uint)pa}");
Console.WriteLine($"b : {b} @ {(uint)pb}");
}
输出
a : test1 @ 51748
b : test1 @ 51748
神奇的是它再次指向原来的位置。这是因为字符串是interned。字符串实习是指在字符串实习池中拥有每个唯一字符串的单个副本,通过哈希表进行查找。这基本上是一个在后台完成的内存节省功能,与问题完全无关。
推荐阅读
- python - 如何在python中使用回车符(\r)和换行符(\n)
- function - Woocommerce - 使用购物车商品和优惠券数据验证优惠券
- cmake - 运行“make all”时忽略 CMake EXCLUDE_FROM_ALL 参数
- android - Kotlin NullPointer 异常 Android
- python - Python Crash Course Alien Game - 用背景 .bmp 图像替换背景颜色
- laravel - 如何获取数组格式而不是返回的对象数组?
- node.js - NestJS 招摇模块无法与通用 crud 控制器一起正常工作
- amazon-web-services - 从列入白名单的 IP 发布到 SQS
- android - 从原生 android 应用服务访问颤振安全存储值
- javascript - 有效过滤嵌套数组