.net – 由未知英雄保存的名单(Of T)?
TL; DR: 正如您在查看源代码时所看到的那样,没有针对潜在算术溢出的保护.但是,如果值为最大值,那么某些事情就是将值设置为Integer.MinValue. <__DynamicallyInvokable()> _ Public Sub Add(ByVal item As T) If (Me._size = Me._items.Length) Then Me.EnsureCapacity((Me._size + 1)) End If Me._items(Me._size++) = item Me._version += 1 End Sub 详细 由于List(Of T)的内部项数组是私有的,我不会使用反射来访问它,因此我决定使用原始的List(Of T)源代码创建自定义列表. 但是,我注意到如果版本达到Integer.MaxValue,则无法防止潜在的算术溢出. Me._version += 1 所以我修改了代码: Me._version = If((Me._version = Integer.MaxValue),Integer.MinValue,(Me._version + 1I)) 现在开始有趣的部分;出于好奇,我设置了一个测试,我使用反射将内部_version字段设置为max. Dim flags As BindingFlags = (BindingFlags.Instance Or BindingFlags.NonPublic) Dim list As New List(Of String) Dim _version As FieldInfo = GetType(List(Of String)).GetField("_version",flags) _version.SetValue(list,Integer.MaxValue) Debug.WriteLine("Count: {0},Version: {1}",list.Count,_version.GetValue(list)) list.Add("str") Debug.WriteLine("Count: {0},_version.GetValue(list)) 我对结果感到震惊:
如果达到最大值,源代码中没有任何内容将字段设置为最小值.我甚至查看了DynamicallyInvokable属性,但据我所知,它不相关. <__DynamicallyInvokable()> _ Public Sub Add(ByVal item As T) If (Me._size = Me._items.Length) Then Me.EnsureCapacity((Me._size + 1)) End If Me._items(Me._size++) = item Me._version += 1 End Sub Private Sub EnsureCapacity(ByVal min As Integer) If (Me._items.Length < min) Then Dim num As Integer = IIf((Me._items.Length = 0),4,(Me._items.Length * 2)) If (num > &H7FEFFFFF) Then num = &H7FEFFFFF End If If (num < min) Then num = min End If Me.Capacity = num End If End Sub <__DynamicallyInvokable()> _ Public Property Capacity As Integer <TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"),__DynamicallyInvokable()> _ Get Return Me._items.Length End Get <__DynamicallyInvokable()> _ Set(ByVal value As Integer) If (value < Me._size) Then ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.value,ExceptionResource.ArgumentOutOfRange_SmallCapacity) End If If (value <> Me._items.Length) Then If (value > 0) Then Dim destinationArray As T() = New T(value - 1) {} If (Me._size > 0) Then Array.Copy(Me._items,destinationArray,Me._size) End If Me._items = destinationArray Else Me._items = List(Of T)._emptyArray End If End If End Set End Property
基类库是用C#编写的,而不是用VB.NET编写的.
默认情况下,C#中的算术运算不会抛出溢出异常.相反,正如你所注意到的那样,他们默默地将价值包裹起来. 这个决定可能是出于效率的原因;不是每个人都同意.可以在以下问题中找到更多信息: > Why doesn’t C# use arithmetic overflow checking by default? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |