我想知道为什么MS决定在INotifyPropertyChanged的设计中使用字符串?
我最初担心的是在每次更改通知上进行字符串比较的费用很高,我想知道是否要保留我的属性名称以帮助进行比较。
但是,鉴于字符串在.Net中是不可变的,我想知道运行时是否足够智能以通过某种哈希表重用字符串实例,所以比较实际上只是一个参考比较?
有没有人知道实施细节,或者如果没有,为什么MS按照他们的方式设计它?
答案 0 :(得分:3)
如果不是string
,你会提出什么建议?它不能是PropertyInfo
,因为并非所有支持它的类型都使用静态类型 - 例如,DataTable
公开自定义属性模型用于绑定目的,因为没有其他类型(通过任何ICustomTypeDescriptor
,TypeDescriptionProvider
或ITypedList
)。
即使 一个PropertyInfo
,或者即使它是PropertyDescriptor
,你也无法对此进行比较:a:它需要一个<获得参考查找的工作很强>很多,b:你甚至都不能保证(特别是PropertyDescriptor
)每次看起来都要回到同一个对象。
这意味着,您最终可能会比较名称(string
) 。
通过使用string
,提升此事件很便宜,并且比较便宜 - 字符串比较非常快,因为大多数属性名称都很短,几乎所有属性都少于30个字符。这将惊人地快速比较,而不是瓶颈。在大多数情况下,“现在该做什么,它已经改变了”将比这个字符串比较花费更多的时间。
我没有在我面前实现,但我希望字符串相等检查基本上是:
所以它甚至不应该是一个问题,除非你的所有属性名称都是:相同的长度,b:非常长的长度
基本上:不要担心。
答案 1 :(得分:2)
无论何时生成新字符串,无论是否存在具有相同内容的字符串,它都将在内存中占用自己的空间。
另一方面,当您将字符串变量显式指定给另一个时,只复制引用。使用常量是另一种节省内存的方法。
通过像哈希表这样的机制重用实例需要更大的开销和比较机制,无论何时创建字符串都会调用。这可能大部分时间都是性能问题,而不仅仅是存储另外几个字节。
答案 2 :(得分:2)
如果您关注实现细节,可以使用Telerik的JustDecompile,看看他们是如何做到的。 至于为什么INotifyPropertyChanged中的字符串,答案是反思。我怀疑他们是否参考了一个实际上微不足道的任务来获得性能。您正在谈论的通知量是多少?由于INotifyPropertyChanged中的字符串比较,正常的WPF / SL应用程序没有性能问题。
答案 3 :(得分:2)
为什么MS按照他们的方式设计它?
因为他们需要一种灵活的方法,而且速度足够快。当属性发生变化时,会发生很多事情,字符串的查找不会成为瓶颈。
属性在一些基础结构中注册,查找将像一个字典意味着HashCode将提供有效的访问。字符串将全部被实现,但这不足以确定引用的不相等性。
保持财产名称简短不会带来任何可衡量的改进,更好地使用有意义的名称。
答案 4 :(得分:0)
我会考虑消费者 - 如果你是数据绑定网格,你已经将属性名称作为你感兴趣的列的字符串。还要考虑提高事件 - 获得{{1并不便宜,而硬编码字符串是。
答案 5 :(得分:0)
我认为字符串比较与其他机制(例如绑定)相比并不昂贵,因此字符串绝对不是瓶颈。
也就是说,在代码中使用常量字符串(我的意思是PropertyChanged(this, new PropertyChangedEventArgs("MyProperty"))
)很快,但我个人更喜欢使用反射来动态获取属性的名称:它需要更多的工作,但它极大地提高了可维护性和减少错误的数量(最常见的是“我重命名我的属性,但我忘了更改PropertyChanged
事件的参数”。