WPF MVVM数据绑定中C#字符串不可变性问题咨询
WPF MVVM 场景下 string 类型的不可变特性不会被任何机制打破
你的猜测完全不成立,OnPropertyChanged 以及WPF绑定机制从底层就不可能消除string的不可变特性,只要字符串内容发生变化,就一定会创建新的字符串对象。
核心逻辑拆解
- string的不可变是.NET CLR层面的底层规则:一旦一个字符串对象被创建分配到内存,它的内容就永远不能被修改,任何对字符串的“修改”操作(拼接、替换、重新赋值不同内容)本质都是生成新的字符串对象,再把变量/属性存储的引用指向新对象,这个规则对所有.NET上层库(包括WPF、各类MVVM框架)一视同仁,没有任何后门可以绕开。
- 结合你的代码,修改
FirstName的完整流程是:- 因为你设置了
UpdateSourceTrigger=PropertyChanged,用户在TextBox每输入一个字符,WPF绑定引擎会先拿到文本框当前生成的全新字符串对象(文本框自身修改显示内容时就已经因为string不可变生成了新对象),调用FirstName的set访问器,把这个新字符串作为value参数传入。 - set访问器里的
user.FirstName != value判断,本质是对比两个字符串引用指向的内容是否相等,这一步不会生成新对象。 - 判断内容不等后执行
user.FirstName = value,这一步只是把User实例中FirstName自动属性的后备字段存储的内存地址,从原来指向旧字符串的地址,改成指向新传入的字符串地址,全程没有修改旧字符串对象的任何内容。 - 调用
OnPropertyChange的作用仅仅是触发PropertyChanged事件,通知绑定引擎“FirstName属性引用的对象换了”,绑定引擎收到通知后会重新调用FirstName的get方法拿到新字符串的引用,刷新UI显示,这个过程只涉及引用的传递,完全不涉及字符串对象本身的修改,根本碰不到string不可变的规则。
- 因为你设置了
常见误解澄清
你觉得“绑定机制会将值持有在同一个对象中”,本质是混淆了「引用」和「对象本身」:
不管是ViewModel的属性还是Model的属性,存储的都不是字符串对象本身,而是指向字符串对象的内存引用。赋值操作只是修改引用指向的地址,从来不会在原内存位置修改字符串内容,这和你在控制台程序里写string s = "a"; s = "b";的执行逻辑没有任何区别,WPF绑定没有做任何特殊处理。
额外提一句,你代码里的FullName属性每次被get访问时执行的字符串拼接操作,也会生成全新的字符串对象,这同样是string不可变特性的正常表现。
内容的提问来源于stack exchange,提问作者Hello
相关产品推荐
相关产品推荐

