diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewCellStyle.cs b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewCellStyle.cs
index 1636b29a6f2..f3979c45c6e 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewCellStyle.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/DataGridViewCellStyle.cs
@@ -418,10 +418,7 @@ public object NullValue
]
public Padding Padding
{
- get
- {
- return this.Properties.GetPadding(PropPadding);
- }
+ get => Properties.GetPadding(PropPadding, out _);
set
{
if (value.Left < 0 || value.Right < 0 || value.Top < 0 || value.Bottom < 0)
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Form.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Form.cs
index 49e4f511e06..b782cc70d43 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/Form.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/Form.cs
@@ -1493,7 +1493,7 @@ public bool KeyPreview {
///
protected Rectangle MaximizedBounds {
get {
- return Properties.GetRectangle(PropMaximizedBounds);
+ return Properties.GetRectangle(PropMaximizedBounds, out _);
}
set {
if (!value.Equals( MaximizedBounds )) {
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/PropertyStore.cs b/src/System.Windows.Forms/src/System/Windows/Forms/PropertyStore.cs
index 4b51f6b782c..2e12d14abc6 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/PropertyStore.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/PropertyStore.cs
@@ -2,894 +2,901 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-namespace System.Windows.Forms {
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Drawing;
- using System;
- using System.Diagnostics;
- using System.Diagnostics.CodeAnalysis;
- using System.Drawing;
-
+namespace System.Windows.Forms
+{
///
- /// This is a small class that can efficiently store property values.
- /// It tries to optimize for size first, "get" access second, and
- /// "set" access third.
+ /// This is a small class that can efficiently store property values.
+ /// It tries to optimize for size first, "get" access second, and
+ /// "set" access third.
///
- internal class PropertyStore {
-
- private static int currentKey;
-
- private IntegerEntry[] intEntries;
- private ObjectEntry[] objEntries;
-
+ internal class PropertyStore
+ {
+ private static int s_currentKey;
+
+ private IntegerEntry[] s_intEntries;
+ private ObjectEntry[] s_objEntries;
+
///
- /// Retrieves an integer value from our property list.
- /// This will set value to zero and return false if the
- /// list does not contain the given key.
+ /// Retrieves an integer value from our property list.
+ /// This will set value to zero and return false if the
+ /// list does not contain the given key.
///
- public bool ContainsInteger(int key) {
- bool found;
- GetInteger(key, out found);
+ public bool ContainsInteger(int key)
+ {
+ GetInteger(key, out bool found);
return found;
}
-
+
///
- /// Retrieves an integer value from our property list.
- /// This will set value to zero and return false if the
- /// list does not contain the given key.
+ /// Retrieves an integer value from our property list.
+ /// This will set value to zero and return false if the
+ /// list does not contain the given key.
///
- public bool ContainsObject(int key) {
- bool found;
- GetObject(key, out found);
+ public bool ContainsObject(int key)
+ {
+ GetObject(key, out bool found);
return found;
}
-
+
///
- /// Creates a new key for this property store. This is NOT
- /// guarded by any thread safety so if you are calling it on
- /// multiple threads you should guard. For our purposes,
- /// we're fine because this is designed to be called in a class
- /// initializer, and we never have the same class hierarchy
- /// initializing on multiple threads at once.
+ /// Creates a new key for this property store. This is NOT
+ /// guarded by any thread safety so if you are calling it on
+ /// multiple threads you should guard. For our purposes,
+ /// we're fine because this is designed to be called in a class
+ /// initializer, and we never have the same class hierarchy
+ /// initializing on multiple threads at once.
///
- public static int CreateKey() {
- return currentKey++;
- }
+ public static int CreateKey() => s_currentKey++;
- public Color GetColor(int key) {
- bool found;
- return GetColor(key, out found);
- }
+ public Color GetColor(int key) => GetColor(key, out _);
- // this is a wrapper around GetObject designed to
- // reduce the boxing hit
- public Color GetColor(int key, out bool found) {
+ ///
+ /// A wrapper around GetObject designed to reduce the boxing hit
+ ///
+ public Color GetColor(int key, out bool found)
+ {
object storedObject = GetObject(key, out found);
-
- if (found) {
- ColorWrapper wrapper = storedObject as ColorWrapper;
-
- if (wrapper != null) {
+ if (found)
+ {
+ if (storedObject is ColorWrapper wrapper)
+ {
return wrapper.Color;
}
-#if DEBUG
- else if (storedObject != null) {
- Debug.Fail("Have non-null object that isnt a color wrapper stored in a color entry!\r\nDid someone SetObject instead of SetColor?");
- }
-#endif
+
+ Debug.Assert(storedObject == null, $"Have non-null object that isnt a color wrapper stored in a color entry!{Environment.NewLine}Did someone SetObject instead of SetColor?");
}
- // we didnt actually find a non-null color wrapper.
- found = false;
- return Color.Empty;
- }
-
- public Padding GetPadding(int key) {
- bool found;
- return GetPadding(key, out found);
+ found = false;
+ return Color.Empty;
}
- // this is a wrapper around GetObject designed to
- // reduce the boxing hit
- public Padding GetPadding(int key, out bool found) {
+ ///
+ /// A wrapper around GetObject designed to reduce the boxing hit.
+ ///
+ public Padding GetPadding(int key, out bool found)
+ {
object storedObject = GetObject(key, out found);
-
- if (found) {
- PaddingWrapper wrapper = storedObject as PaddingWrapper;
-
-
- if (wrapper != null) {
+ if (found)
+ {
+ if (storedObject is PaddingWrapper wrapper)
+ {
return wrapper.Padding;
- }
-#if DEBUG
- else if (storedObject != null) {
- Debug.Fail("Have non-null object that isnt a padding wrapper stored in a padding entry!\r\nDid someone SetObject instead of SetPadding?");
}
-#endif
+
+ Debug.Assert(storedObject == null, $"Have non-null object that isnt a padding wrapper stored in a padding entry!{Environment.NewLine}Did someone SetObject instead of SetPadding?");
}
-
- // we didnt actually find a non-null padding wrapper.
+
found = false;
- return Padding.Empty;
- }
-#if false // FXCOP currently not used
- public Size GetSize(int key) {
- bool found;
- return GetSize(key, out found);
+ return Padding.Empty;
}
-#endif
- // this is a wrapper around GetObject designed to
- // reduce the boxing hit
- public Size GetSize(int key, out bool found) {
+ ///
+ /// A wrapper around GetObject designed to reduce the boxing hit.
+ ///
+ public Size GetSize(int key, out bool found)
+ {
object storedObject = GetObject(key, out found);
-
- if (found) {
- SizeWrapper wrapper = storedObject as SizeWrapper;
- if (wrapper != null) {
+ if (found)
+ {
+ if (storedObject is SizeWrapper wrapper)
+ {
return wrapper.Size;
}
-#if DEBUG
- else if (storedObject != null) {
- Debug.Fail("Have non-null object that isnt a padding wrapper stored in a padding entry!\r\nDid someone SetObject instead of SetPadding?");
- }
-#endif
+
+ Debug.Assert(storedObject == null, $"Have non-null object that isnt a padding wrapper stored in a padding entry!{Environment.NewLine}Did someone SetObject instead of SetPadding?");
}
- // we didnt actually find a non-null size wrapper.
+
found = false;
- return Size.Empty;
+ return Size.Empty;
}
- public Rectangle GetRectangle(int key) {
- bool found;
- return GetRectangle(key, out found);
- }
-
- // this is a wrapper around GetObject designed to
- // reduce the boxing hit
- public Rectangle GetRectangle(int key, out bool found) {
+ ///
+ /// A wrapper around GetObject designed to reduce the boxing hit.
+ ///
+ public Rectangle GetRectangle(int key, out bool found)
+ {
object storedObject = GetObject(key, out found);
-
- if (found) {
- RectangleWrapper wrapper = storedObject as RectangleWrapper;
- if (wrapper != null) {
+ if (found)
+ {
+ if (storedObject is RectangleWrapper wrapper)
+ {
return wrapper.Rectangle;
}
-#if DEBUG
- else if (storedObject != null) {
- Debug.Fail("Have non-null object that isnt a Rectangle wrapper stored in a Rectangle entry!\r\nDid someone SetObject instead of SetRectangle?");
- }
-#endif
+
+ Debug.Assert(storedObject == null, $"Have non-null object that isnt a Rectangle wrapper stored in a Rectangle entry!{Environment.NewLine}Did someone SetObject instead of SetRectangle?");
}
- // we didnt actually find a non-null rectangle wrapper.
+
found = false;
- return Rectangle.Empty;
+ return Rectangle.Empty;
}
///
- /// Retrieves an integer value from our property list.
- /// This will set value to zero and return false if the
- /// list does not contain the given key.
+ /// Retrieves an integer value from our property list.
+ /// This will set value to zero and return false if the
+ /// list does not contain the given key.
///
- public int GetInteger(int key) {
- bool found;
- return GetInteger(key, out found);
- }
-
+ public int GetInteger(int key) => GetInteger(key, out _);
+
///
- /// Retrieves an integer value from our property list.
- /// This will set value to zero and return false if the
- /// list does not contain the given key.
+ /// Retrieves an integer value from our property list.
+ /// This will set value to zero and return false if the
+ /// list does not contain the given key.
///
- public int GetInteger(int key, out bool found) {
-
- int value = 0;
- int index;
- short element;
- short keyIndex = SplitKey(key, out element);
-
- found = false;
-
- if (LocateIntegerEntry(keyIndex, out index)) {
- // We have found the relevant entry. See if
- // the bitmask indicates the value is used.
- //
- if (((1 << element) & intEntries[index].Mask) != 0) {
-
- found = true;
-
- switch(element) {
- case 0:
- value = intEntries[index].Value1;
- break;
-
- case 1:
- value = intEntries[index].Value2;
- break;
-
- case 2:
- value = intEntries[index].Value3;
- break;
-
- case 3:
- value = intEntries[index].Value4;
- break;
-
- default:
- Debug.Fail("Invalid element obtained from LocateIntegerEntry");
- break;
- }
- }
+ public int GetInteger(int key, out bool found)
+ {
+ short keyIndex = SplitKey(key, out short element);
+ if (!LocateIntegerEntry(keyIndex, out int index))
+ {
+ found = false;
+ return default(int);
+ }
+
+ // We have found the relevant entry. See if
+ // the bitmask indicates the value is used.
+ if (((1 << element) & s_intEntries[index].Mask) == 0)
+ {
+ found = false;
+ return default(int);
+ }
+
+ found = true;
+ switch (element)
+ {
+ case 0:
+ return s_intEntries[index].Value1;
+ case 1:
+ return s_intEntries[index].Value2;
+ case 2:
+ return s_intEntries[index].Value3;
+ case 3:
+ return s_intEntries[index].Value4;
+ default:
+ Debug.Fail("Invalid element obtained from LocateIntegerEntry");
+ return default(int);
}
-
- return value;
}
-
+
///
- /// Retrieves an object value from our property list.
- /// This will set value to null and return false if the
- /// list does not contain the given key.
+ /// Retrieves an object value from our property list.
+ /// This will set value to null and return false if the
+ /// list does not contain the given key.
///
- public object GetObject(int key) {
- bool found;
- return GetObject(key, out found);
- }
+ public object GetObject(int key) => GetObject(key, out _);
///
- /// Retrieves an object value from our property list.
- /// This will set value to null and return false if the
- /// list does not contain the given key.
+ /// Retrieves an object value from our property list.
+ /// This will set value to null and return false if the
+ /// list does not contain the given key.
///
- public object GetObject(int key, out bool found) {
-
- object value = null;
- int index;
- short element;
- short keyIndex = SplitKey(key, out element);
-
- found = false;
-
- if (LocateObjectEntry(keyIndex, out index)) {
- // We have found the relevant entry. See if
- // the bitmask indicates the value is used.
- //
- if (((1 << element) & objEntries[index].Mask) != 0) {
-
- found = true;
-
- switch(element) {
- case 0:
- value = objEntries[index].Value1;
- break;
-
- case 1:
- value = objEntries[index].Value2;
- break;
-
- case 2:
- value = objEntries[index].Value3;
- break;
-
- case 3:
- value = objEntries[index].Value4;
- break;
-
- default:
- Debug.Fail("Invalid element obtained from LocateObjectEntry");
- break;
- }
- }
+ public object GetObject(int key, out bool found)
+ {
+ short keyIndex = SplitKey(key, out short element);
+ if (!LocateObjectEntry(keyIndex, out int index))
+ {
+ found = false;
+ return null;
+ }
+
+ // We have found the relevant entry. See if
+ // the bitmask indicates the value is used.
+ if (((1 << element) & s_objEntries[index].Mask) == 0)
+ {
+ found = false;
+ return null;
}
- return value;
+ found = true;
+ switch (element)
+ {
+ case 0:
+ return s_objEntries[index].Value1;
+ case 1:
+ return s_objEntries[index].Value2;
+ case 2:
+ return s_objEntries[index].Value3;
+ case 3:
+ return s_objEntries[index].Value4;
+ default:
+ Debug.Fail("Invalid element obtained from LocateObjectEntry");
+ return null;
+ }
}
-
///
- /// Locates the requested entry in our array if entries. This does
- /// not do the mask check to see if the entry is currently being used,
- /// but it does locate the entry. If the entry is found, this returns
- /// true and fills in index and element. If the entry is not found,
- /// this returns false. If the entry is not found, index will contain
- /// the insert point at which one would add a new element.
+ /// Locates the requested entry in our array if entries. This does
+ /// not do the mask check to see if the entry is currently being used,
+ /// but it does locate the entry. If the entry is found, this returns
+ /// true and fills in index and element. If the entry is not found,
+ /// this returns false. If the entry is not found, index will contain
+ /// the insert point at which one would add a new element.
///
- private bool LocateIntegerEntry(short entryKey, out int index) {
- if (intEntries != null) {
- int length = intEntries.Length;
- if (length <= 16) {
- //if the array is small enough, we unroll the binary search to be more efficient.
- //usually the performance gain is around 10% to 20%
- //DON'T change this code unless you are very confident!
- index = 0;
- int midPoint = length / 2;
- if (intEntries[midPoint].Key <= entryKey) {
- index = midPoint;
- }
- //we don't move this inside the previous if branch since this catches both the case
- //index == 0 and index = midPoint
- if (intEntries[index].Key == entryKey) {
+ private bool LocateIntegerEntry(short entryKey, out int index)
+ {
+ if (s_intEntries == null)
+ {
+ index = 0;
+ return false;
+ }
+
+ int length = s_intEntries.Length;
+ if (length <= 16)
+ {
+ // If the array is small enough, we unroll the binary search to be more efficient.
+ // Usually the performance gain is around 10% to 20%
+ // DON'T change this code unless you are very confident!
+ index = 0;
+ int midPoint = length / 2;
+ if (s_intEntries[midPoint].Key <= entryKey)
+ {
+ index = midPoint;
+ }
+
+ // We don't move this inside the previous if branch since this catches both
+ // the case index == 0 and index = midPoint
+ if (s_intEntries[index].Key == entryKey)
+ {
+ return true;
+ }
+
+ midPoint = (length + 1) / 4;
+ if (s_intEntries[index + midPoint].Key <= entryKey)
+ {
+ index += midPoint;
+ if (s_intEntries[index].Key == entryKey)
+ {
return true;
}
-
- midPoint = (length + 1) / 4;
- if (intEntries[index + midPoint].Key <= entryKey) {
- index += midPoint;
- if (intEntries[index].Key == entryKey) {
- return true;
- }
- }
-
- midPoint = (length + 3) / 8;
- if (intEntries[index + midPoint].Key <= entryKey) {
- index += midPoint;
- if (intEntries[index].Key == entryKey) {
- return true;
- }
- }
-
- midPoint = (length + 7) / 16;
- if (intEntries[index + midPoint].Key <= entryKey) {
- index += midPoint;
- if (intEntries[index].Key == entryKey) {
- return true;
- }
+ }
+
+ midPoint = (length + 3) / 8;
+ if (s_intEntries[index + midPoint].Key <= entryKey)
+ {
+ index += midPoint;
+ if (s_intEntries[index].Key == entryKey)
+ {
+ return true;
}
+ }
- Debug.Assert(index < length);
- if (entryKey > intEntries[index].Key) {
- index++;
+ midPoint = (length + 7) / 16;
+ if (s_intEntries[index + midPoint].Key <= entryKey)
+ {
+ index += midPoint;
+ if (s_intEntries[index].Key == entryKey)
+ {
+ return true;
}
- Debug_VerifyLocateIntegerEntry(index, entryKey, length);
- return false;
}
- else {
- // Entries are stored in numerical order by key index so we can
- // do a binary search on them.
- //
- int max = length - 1;
- int min = 0;
- int idx = 0;
-
- do {
- idx = (max + min) / 2;
- short currentKeyIndex = intEntries[idx].Key;
-
- if (currentKeyIndex == entryKey) {
- index = idx;
- return true;
- }
- else if (entryKey < currentKeyIndex) {
- max = idx - 1;
- }
- else {
- min = idx + 1;
- }
+
+ Debug.Assert(index < length);
+ if (entryKey > s_intEntries[index].Key)
+ {
+ index++;
+ }
+
+ Debug_VerifyLocateIntegerEntry(index, entryKey, length);
+ return false;
+ }
+ else
+ {
+ // Entries are stored in numerical order by key index so we can
+ // do a binary search on them.
+ int max = length - 1;
+ int min = 0;
+ int idx = 0;
+
+ do
+ {
+ idx = (max + min) / 2;
+ short currentKeyIndex = s_intEntries[idx].Key;
+
+ if (currentKeyIndex == entryKey)
+ {
+ index = idx;
+ return true;
}
- while (max >= min);
-
- // Didn't find the index. Setup our output
- // appropriately
- //
- index = idx;
- if (entryKey > intEntries[idx].Key) {
- index++;
+ else if (entryKey < currentKeyIndex)
+ {
+ max = idx - 1;
+ }
+ else
+ {
+ min = idx + 1;
}
- return false;
}
- }
- else {
- index = 0;
+ while (max >= min);
+
+ // Didn't find the index. Setup our output appropriately
+ index = idx;
+ if (entryKey > s_intEntries[idx].Key)
+ {
+ index++;
+ }
+
return false;
}
}
-
+
///
- /// Locates the requested entry in our array if entries. This does
- /// not do the mask check to see if the entry is currently being used,
- /// but it does locate the entry. If the entry is found, this returns
- /// true and fills in index and element. If the entry is not found,
- /// this returns false. If the entry is not found, index will contain
- /// the insert point at which one would add a new element.
+ /// Locates the requested entry in our array if entries. This does
+ /// not do the mask check to see if the entry is currently being used,
+ /// but it does locate the entry. If the entry is found, this returns
+ /// true and fills in index and element. If the entry is not found,
+ /// this returns false. If the entry is not found, index will contain
+ /// the insert point at which one would add a new element.
///
- private bool LocateObjectEntry(short entryKey, out int index) {
- if (objEntries != null) {
- int length = objEntries.Length;
+ private bool LocateObjectEntry(short entryKey, out int index)
+ {
+ if (s_objEntries != null)
+ {
+ int length = s_objEntries.Length;
Debug.Assert(length > 0);
- if (length <= 16) {
- //if the array is small enough, we unroll the binary search to be more efficient.
- //usually the performance gain is around 10% to 20%
- //DON'T change this code unless you are very confident!
+ if (length <= 16)
+ {
+ // If the array is small enough, we unroll the binary search to be more efficient.
+ // Usually the performance gain is around 10% to 20%
+ // DON'T change this code unless you are very confident!
index = 0;
int midPoint = length / 2;
- if (objEntries[midPoint].Key <= entryKey) {
+ if (s_objEntries[midPoint].Key <= entryKey)
+ {
index = midPoint;
}
- //we don't move this inside the previous if branch since this catches both the case
- //index == 0 and index = midPoint
- if (objEntries[index].Key == entryKey) {
+
+ // We don't move this inside the previous if branch since this catches
+ // both the case index == 0 and index = midPoint
+ if (s_objEntries[index].Key == entryKey)
+ {
return true;
}
-
+
midPoint = (length + 1) / 4;
- if (objEntries[index + midPoint].Key <= entryKey) {
+ if (s_objEntries[index + midPoint].Key <= entryKey)
+ {
index += midPoint;
- if (objEntries[index].Key == entryKey) {
+ if (s_objEntries[index].Key == entryKey)
+ {
return true;
}
}
-
+
midPoint = (length + 3) / 8;
- if (objEntries[index + midPoint].Key <= entryKey) {
+ if (s_objEntries[index + midPoint].Key <= entryKey)
+ {
index += midPoint;
- if (objEntries[index].Key == entryKey) {
+ if (s_objEntries[index].Key == entryKey)
+ {
return true;
}
}
-
+
midPoint = (length + 7) / 16;
- if (objEntries[index + midPoint].Key <= entryKey) {
+ if (s_objEntries[index + midPoint].Key <= entryKey)
+ {
index += midPoint;
- if (objEntries[index].Key == entryKey) {
+ if (s_objEntries[index].Key == entryKey)
+ {
return true;
}
}
Debug.Assert(index < length);
- if (entryKey > objEntries[index].Key) {
+ if (entryKey > s_objEntries[index].Key)
+ {
index++;
}
+
Debug_VerifyLocateObjectEntry(index, entryKey, length);
return false;
}
- else {
+ else
+ {
// Entries are stored in numerical order by key index so we can
// do a binary search on them.
- //
int max = length - 1;
int min = 0;
int idx = 0;
-
- do {
+
+ do
+ {
idx = (max + min) / 2;
- short currentKeyIndex = objEntries[idx].Key;
-
- if (currentKeyIndex == entryKey) {
+ short currentKeyIndex = s_objEntries[idx].Key;
+
+ if (currentKeyIndex == entryKey)
+ {
index = idx;
return true;
}
- else if (entryKey < currentKeyIndex) {
+ else if (entryKey < currentKeyIndex)
+ {
max = idx - 1;
}
- else {
+ else
+ {
min = idx + 1;
}
}
while (max >= min);
-
- // Didn't find the index. Setup our output
- // appropriately
- //
+
+ // Didn't find the index. Setup our output appropriately
index = idx;
- if (entryKey > objEntries[idx].Key) {
+ if (entryKey > s_objEntries[idx].Key)
+ {
index++;
}
+
return false;
}
}
- else {
+ else
+ {
index = 0;
return false;
}
}
-/*
- public Color RemoveColor(int key) {
- RemoveObject(key);
- }
-*/
+
///
- /// Removes the given key from the array
+ /// Removes the given key from the array
///
- public void RemoveInteger(int key) {
- int index;
- short element;
- short entryKey = SplitKey(key, out element);
-
- if (LocateIntegerEntry(entryKey, out index)) {
- if (((1 << element) & intEntries[index].Mask) == 0) {
- // this element is not being used - return right away
- return;
- }
-
- // declare that the element is no longer used
- intEntries[index].Mask &= (short) (~((short)(1 << element)));
-
- if (intEntries[index].Mask == 0) {
- // this object entry is no longer in use - let's remove it all together
- // not great for perf but very simple and we don't expect to remove much
- IntegerEntry[] newEntries = new IntegerEntry[intEntries.Length - 1];
- if (index > 0) {
- Array.Copy(intEntries, 0, newEntries, 0, index);
- }
- if (index < newEntries.Length) {
- Debug.Assert(intEntries.Length - index - 1 > 0);
- Array.Copy(intEntries, index + 1, newEntries, index, intEntries.Length - index - 1);
- }
- intEntries = newEntries;
- }
- else {
- // this object entry is still in use - let's just clean up the deleted element
- switch (element)
- {
- case 0:
- intEntries[index].Value1 = 0;
- break;
+ public void RemoveInteger(int key)
+ {
+ short entryKey = SplitKey(key, out short element);
+ if (!LocateIntegerEntry(entryKey, out int index))
+ {
+ return;
+ }
- case 1:
- intEntries[index].Value2 = 0;
- break;
+ if (((1 << element) & s_intEntries[index].Mask) == 0)
+ {
+ // this element is not being used - return right away
+ return;
+ }
- case 2:
- intEntries[index].Value3 = 0;
- break;
+ // declare that the element is no longer used
+ s_intEntries[index].Mask &= (short)(~((short)(1 << element)));
- case 3:
- intEntries[index].Value4 = 0;
- break;
+ if (s_intEntries[index].Mask == 0)
+ {
+ // This object entry is no longer in use - let's remove it all together
+ // not great for perf but very simple and we don't expect to remove much
+ IntegerEntry[] newEntries = new IntegerEntry[s_intEntries.Length - 1];
+ if (index > 0)
+ {
+ Array.Copy(s_intEntries, 0, newEntries, 0, index);
+ }
+ if (index < newEntries.Length)
+ {
+ Debug.Assert(s_intEntries.Length - index - 1 > 0);
+ Array.Copy(s_intEntries, index + 1, newEntries, index, s_intEntries.Length - index - 1);
+ }
- default:
- Debug.Fail("Invalid element obtained from LocateIntegerEntry");
- break;
- }
+ s_intEntries = newEntries;
+ }
+ else
+ {
+ // This object entry is still in use - let's just clean up the deleted element
+ switch (element)
+ {
+ case 0:
+ s_intEntries[index].Value1 = 0;
+ break;
+
+ case 1:
+ s_intEntries[index].Value2 = 0;
+ break;
+
+ case 2:
+ s_intEntries[index].Value3 = 0;
+ break;
+
+ case 3:
+ s_intEntries[index].Value4 = 0;
+ break;
+
+ default:
+ Debug.Fail("Invalid element obtained from LocateIntegerEntry");
+ break;
}
}
}
///
- /// Removes the given key from the array
+ /// Removes the given key from the array
///
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
public void RemoveObject(int key)
{
- int index;
- short element;
- short entryKey = SplitKey(key, out element);
-
- if (LocateObjectEntry(entryKey, out index)) {
- if (((1 << element) & objEntries[index].Mask) == 0) {
- // this element is not being used - return right away
- return;
- }
-
- // declare that the element is no longer used
- objEntries[index].Mask &= (short)(~((short)(1 << element)));
-
- if (objEntries[index].Mask == 0) {
- // this object entry is no longer in use - let's remove it all together
- // not great for perf but very simple and we don't expect to remove much
- if (objEntries.Length == 1)
+ short entryKey = SplitKey(key, out short element);
+ if (!LocateObjectEntry(entryKey, out int index))
+ {
+ return;
+ }
+
+ if (((1 << element) & s_objEntries[index].Mask) == 0)
+ {
+ // This element is not being used - return right away
+ return;
+ }
+
+ // Declare that the element is no longer used
+ s_objEntries[index].Mask &= (short)(~((short)(1 << element)));
+
+ if (s_objEntries[index].Mask == 0)
+ {
+ // This object entry is no longer in use - let's remove it all together
+ // not great for perf but very simple and we don't expect to remove much
+ if (s_objEntries.Length == 1)
+ {
+ // Instead of allocating an array of length 0, we simply reset the array to null.
+ s_objEntries = null;
+ }
+ else
+ {
+ ObjectEntry[] newEntries = new ObjectEntry[s_objEntries.Length - 1];
+ if (index > 0)
{
- // instead of allocating an array of length 0, we simply reset the array to null.
- objEntries = null;
+ Array.Copy(s_objEntries, 0, newEntries, 0, index);
}
- else
+ if (index < newEntries.Length)
{
- ObjectEntry[] newEntries = new ObjectEntry[objEntries.Length - 1];
- if (index > 0)
- {
- Array.Copy(objEntries, 0, newEntries, 0, index);
- }
- if (index < newEntries.Length)
- {
- Debug.Assert(objEntries.Length - index - 1 > 0);
- Array.Copy(objEntries, index + 1, newEntries, index, objEntries.Length - index - 1);
- }
- objEntries = newEntries;
+ Debug.Assert(s_objEntries.Length - index - 1 > 0);
+ Array.Copy(s_objEntries, index + 1, newEntries, index, s_objEntries.Length - index - 1);
}
+ s_objEntries = newEntries;
}
- else {
- // this object entry is still in use - let's just clean up the deleted element
- switch (element)
- {
- case 0:
- objEntries[index].Value1 = null;
- break;
-
- case 1:
- objEntries[index].Value2 = null;
- break;
-
- case 2:
- objEntries[index].Value3 = null;
- break;
-
- case 3:
- objEntries[index].Value4 = null;
- break;
-
- default:
- Debug.Fail("Invalid element obtained from LocateObjectEntry");
- break;
- }
+ }
+ else
+ {
+ // This object entry is still in use - let's just clean up the deleted element
+ switch (element)
+ {
+ case 0:
+ s_objEntries[index].Value1 = null;
+ break;
+
+ case 1:
+ s_objEntries[index].Value2 = null;
+ break;
+
+ case 2:
+ s_objEntries[index].Value3 = null;
+ break;
+
+ case 3:
+ s_objEntries[index].Value4 = null;
+ break;
+
+ default:
+ Debug.Fail("Invalid element obtained from LocateObjectEntry");
+ break;
}
}
}
- public void SetColor(int key, Color value) {
- bool found;
- object storedObject = GetObject(key, out found);
-
- if (!found) {
+ public void SetColor(int key, Color value)
+ {
+ object storedObject = GetObject(key, out bool found);
+ if (!found)
+ {
SetObject(key, new ColorWrapper(value));
}
- else {
- ColorWrapper wrapper = storedObject as ColorWrapper;
- if(wrapper != null) {
+ else
+ {
+ if (storedObject is ColorWrapper wrapper)
+ {
// re-using the wrapper reduces the boxing hit.
wrapper.Color = value;
}
- else {
+ else
+ {
Debug.Assert(storedObject == null, "object should either be null or ColorWrapper"); // could someone have SetObject to this key behind our backs?
SetObject(key, new ColorWrapper(value));
}
-
- }
+
+ }
}
- public void SetPadding(int key, Padding value) {
- bool found;
- object storedObject = GetObject(key, out found);
- if (!found) {
+ public void SetPadding(int key, Padding value)
+ {
+ object storedObject = GetObject(key, out bool found);
+ if (!found)
+ {
SetObject(key, new PaddingWrapper(value));
}
- else {
- PaddingWrapper wrapper = storedObject as PaddingWrapper;
- if(wrapper != null) {
+ else
+ {
+ if (storedObject is PaddingWrapper wrapper)
+ {
// re-using the wrapper reduces the boxing hit.
wrapper.Padding = value;
}
- else {
+ else
+ {
Debug.Assert(storedObject == null, "object should either be null or PaddingWrapper"); // could someone have SetObject to this key behind our backs?
SetObject(key, new PaddingWrapper(value));
}
-
- }
+
+ }
}
- public void SetRectangle(int key, Rectangle value) {
-
- bool found;
- object storedObject = GetObject(key, out found);
-
- if (!found) {
+
+ public void SetRectangle(int key, Rectangle value)
+ {
+ object storedObject = GetObject(key, out bool found);
+ if (!found)
+ {
SetObject(key, new RectangleWrapper(value));
}
- else {
- RectangleWrapper wrapper = storedObject as RectangleWrapper;
- if(wrapper != null) {
+ else
+ {
+ if (storedObject is RectangleWrapper wrapper)
+ {
// re-using the wrapper reduces the boxing hit.
wrapper.Rectangle = value;
}
- else {
+ else
+ {
Debug.Assert(storedObject == null, "object should either be null or RectangleWrapper"); // could someone have SetObject to this key behind our backs?
SetObject(key, new RectangleWrapper(value));
}
-
- }
-
- }
- public void SetSize(int key, Size value) {
-
- bool found;
- object storedObject = GetObject(key, out found);
-
- if (!found) {
+ }
+ }
+
+ public void SetSize(int key, Size value)
+ {
+ object storedObject = GetObject(key, out bool found);
+ if (!found)
+ {
SetObject(key, new SizeWrapper(value));
}
- else {
- SizeWrapper wrapper = storedObject as SizeWrapper;
- if(wrapper != null) {
+ else
+ {
+ if (storedObject is SizeWrapper wrapper)
+ {
// re-using the wrapper reduces the boxing hit.
wrapper.Size = value;
}
- else {
+ else
+ {
Debug.Assert(storedObject == null, "object should either be null or SizeWrapper"); // could someone have SetObject to this key behind our backs?
SetObject(key, new SizeWrapper(value));
}
-
- }
+
+ }
}
+
///
- /// Stores the given value in the key.
+ /// Stores the given value in the key.
///
- public void SetInteger(int key, int value) {
- int index;
- short element;
- short entryKey = SplitKey(key, out element);
-
- if (!LocateIntegerEntry(entryKey, out index)) {
-
+ public void SetInteger(int key, int value)
+ {
+ short entryKey = SplitKey(key, out short element);
+ if (!LocateIntegerEntry(entryKey, out int index))
+ {
// We must allocate a new entry.
- //
- if (intEntries != null) {
- IntegerEntry[] newEntries = new IntegerEntry[intEntries.Length + 1];
-
- if (index > 0) {
- Array.Copy(intEntries, 0, newEntries, 0, index);
+ if (s_intEntries != null)
+ {
+ IntegerEntry[] newEntries = new IntegerEntry[s_intEntries.Length + 1];
+
+ if (index > 0)
+ {
+ Array.Copy(s_intEntries, 0, newEntries, 0, index);
}
-
- if (intEntries.Length - index > 0) {
- Array.Copy(intEntries, index, newEntries, index + 1, intEntries.Length - index);
+
+ if (s_intEntries.Length - index > 0)
+ {
+ Array.Copy(s_intEntries, index, newEntries, index + 1, s_intEntries.Length - index);
}
-
- intEntries = newEntries;
+
+ s_intEntries = newEntries;
}
- else {
- intEntries = new IntegerEntry[1];
+ else
+ {
+ s_intEntries = new IntegerEntry[1];
Debug.Assert(index == 0, "LocateIntegerEntry should have given us a zero index.");
}
-
- intEntries[index].Key = entryKey;
+
+ s_intEntries[index].Key = entryKey;
}
-
+
// Now determine which value to set.
- //
- switch(element) {
+ switch (element)
+ {
case 0:
- intEntries[index].Value1 = value;
+ s_intEntries[index].Value1 = value;
break;
-
+
case 1:
- intEntries[index].Value2 = value;
+ s_intEntries[index].Value2 = value;
break;
-
+
case 2:
- intEntries[index].Value3 = value;
+ s_intEntries[index].Value3 = value;
break;
-
+
case 3:
- intEntries[index].Value4 = value;
+ s_intEntries[index].Value4 = value;
break;
-
+
default:
Debug.Fail("Invalid element obtained from LocateIntegerEntry");
break;
}
- intEntries[index].Mask = (short)((1 << element) | (ushort)(intEntries[index].Mask));
+ s_intEntries[index].Mask = (short)((1 << element) | (ushort)(s_intEntries[index].Mask));
}
-
+
///
- /// Stores the given value in the key.
+ /// Stores the given value in the key.
///
- public void SetObject(int key, object value) {
- int index;
- short element;
- short entryKey = SplitKey(key, out element);
-
- if (!LocateObjectEntry(entryKey, out index)) {
-
+ public void SetObject(int key, object value)
+ {
+ short entryKey = SplitKey(key, out short element);
+ if (!LocateObjectEntry(entryKey, out int index))
+ {
// We must allocate a new entry.
- //
- if (objEntries != null) {
- ObjectEntry[] newEntries = new ObjectEntry[objEntries.Length + 1];
-
- if (index > 0) {
- Array.Copy(objEntries, 0, newEntries, 0, index);
+ if (s_objEntries != null)
+ {
+ ObjectEntry[] newEntries = new ObjectEntry[s_objEntries.Length + 1];
+
+ if (index > 0)
+ {
+ Array.Copy(s_objEntries, 0, newEntries, 0, index);
}
-
- if (objEntries.Length - index > 0) {
- Array.Copy(objEntries, index, newEntries, index + 1, objEntries.Length - index);
+
+ if (s_objEntries.Length - index > 0)
+ {
+ Array.Copy(s_objEntries, index, newEntries, index + 1, s_objEntries.Length - index);
}
-
- objEntries = newEntries;
+
+ s_objEntries = newEntries;
}
- else {
- objEntries = new ObjectEntry[1];
+ else
+ {
+ s_objEntries = new ObjectEntry[1];
Debug.Assert(index == 0, "LocateObjectEntry should have given us a zero index.");
}
-
- objEntries[index].Key = entryKey;
+
+ s_objEntries[index].Key = entryKey;
}
-
+
// Now determine which value to set.
- //
- switch(element) {
+ switch (element)
+ {
case 0:
- objEntries[index].Value1 = value;
+ s_objEntries[index].Value1 = value;
break;
-
+
case 1:
- objEntries[index].Value2 = value;
+ s_objEntries[index].Value2 = value;
break;
-
+
case 2:
- objEntries[index].Value3 = value;
+ s_objEntries[index].Value3 = value;
break;
-
+
case 3:
- objEntries[index].Value4 = value;
+ s_objEntries[index].Value4 = value;
break;
-
+
default:
Debug.Fail("Invalid element obtained from LocateObjectEntry");
break;
}
-
- objEntries[index].Mask = (short)((ushort)(objEntries[index].Mask)|(1 << element));
+
+ s_objEntries[index].Mask = (short)((ushort)(s_objEntries[index].Mask) | (1 << element));
}
-
+
///
- /// Takes the given key and splits it into an index
- /// and an element.
+ /// Takes the given key and splits it into an index and an element.
///
- private short SplitKey(int key, out short element) {
+ private short SplitKey(int key, out short element)
+ {
element = (short)(key & 0x00000003);
return (short)(key & 0xFFFFFFFC);
}
[Conditional("DEBUG_PROPERTYSTORE")]
- private void Debug_VerifyLocateIntegerEntry(int index, short entryKey, int length) {
+ private void Debug_VerifyLocateIntegerEntry(int index, short entryKey, int length)
+ {
int max = length - 1;
int min = 0;
int idx = 0;
-
- do {
+
+ do
+ {
idx = (max + min) / 2;
- short currentKeyIndex = intEntries[idx].Key;
-
- if (currentKeyIndex == entryKey) {
+ short currentKeyIndex = s_intEntries[idx].Key;
+
+ if (currentKeyIndex == entryKey)
+ {
Debug.Assert(index == idx, "GetIntegerEntry in property store broken. index is " + index + " while it should be " + idx + "length of the array is " + length);
}
- else if (entryKey < currentKeyIndex) {
+ else if (entryKey < currentKeyIndex)
+ {
max = idx - 1;
}
- else {
+ else
+ {
min = idx + 1;
}
}
while (max >= min);
-
+
// shouldn't find the index if we run this debug code
- if (entryKey > intEntries[idx].Key) {
+ if (entryKey > s_intEntries[idx].Key)
+ {
idx++;
- }
+ }
Debug.Assert(index == idx, "GetIntegerEntry in property store broken. index is " + index + " while it should be " + idx + "length of the array is " + length);
}
[Conditional("DEBUG_PROPERTYSTORE")]
- private void Debug_VerifyLocateObjectEntry(int index, short entryKey, int length) {
+ private void Debug_VerifyLocateObjectEntry(int index, short entryKey, int length)
+ {
int max = length - 1;
int min = 0;
int idx = 0;
-
- do {
+
+ do
+ {
idx = (max + min) / 2;
- short currentKeyIndex = objEntries[idx].Key;
-
- if (currentKeyIndex == entryKey) {
+ short currentKeyIndex = s_objEntries[idx].Key;
+
+ if (currentKeyIndex == entryKey)
+ {
Debug.Assert(index == idx, "GetObjEntry in property store broken. index is " + index + " while is should be " + idx + "length of the array is " + length);
}
- else if (entryKey < currentKeyIndex) {
+ else if (entryKey < currentKeyIndex)
+ {
max = idx - 1;
}
- else {
+ else
+ {
min = idx + 1;
}
}
while (max >= min);
-
- if (entryKey > objEntries[idx].Key) {
+
+ if (entryKey > s_objEntries[idx].Key)
+ {
idx++;
- }
+ }
Debug.Assert(index == idx, "GetObjEntry in property store broken. index is " + index + " while is should be " + idx + "length of the array is " + length);
}
-
+
///
- /// Stores the relationship between a key and a value.
- /// We do not want to be so inefficient that we require
- /// four bytes for each four byte property, so use an algorithm
- /// that uses the bottom two bits of the key to identify
- /// one of four elements in an entry.
+ /// Stores the relationship between a key and a value.
+ /// We do not want to be so inefficient that we require
+ /// four bytes for each four byte property, so use an algorithm
+ /// that uses the bottom two bits of the key to identify
+ /// one of four elements in an entry.
///
- private struct IntegerEntry {
+ private struct IntegerEntry
+ {
public short Key;
public short Mask; // only lower four bits are used; mask of used values.
public int Value1;
@@ -897,15 +904,16 @@ private struct IntegerEntry {
public int Value3;
public int Value4;
}
-
+
///
- /// Stores the relationship between a key and a value.
- /// We do not want to be so inefficient that we require
- /// four bytes for each four byte property, so use an algorithm
- /// that uses the bottom two bits of the key to identify
- /// one of four elements in an entry.
+ /// Stores the relationship between a key and a value.
+ /// We do not want to be so inefficient that we require
+ /// four bytes for each four byte property, so use an algorithm
+ /// that uses the bottom two bits of the key to identify
+ /// one of four elements in an entry.
///
- private struct ObjectEntry {
+ private struct ObjectEntry
+ {
public short Key;
public short Mask; // only lower four bits are used; mask of used values.
public object Value1;
@@ -914,33 +922,44 @@ private struct ObjectEntry {
public object Value4;
}
-
- private sealed class ColorWrapper {
+ private sealed class ColorWrapper
+ {
public Color Color;
- public ColorWrapper(Color color){
- this.Color = color;
+
+ public ColorWrapper(Color color)
+ {
+ Color = color;
}
}
-
- private sealed class PaddingWrapper{
+ private sealed class PaddingWrapper
+ {
public Padding Padding;
- public PaddingWrapper(Padding padding){
- this.Padding = padding;
+
+ public PaddingWrapper(Padding padding)
+ {
+ Padding = padding;
}
}
- private sealed class RectangleWrapper{
+
+ private sealed class RectangleWrapper
+ {
public Rectangle Rectangle;
- public RectangleWrapper(Rectangle rectangle){
- this.Rectangle = rectangle;
+
+ public RectangleWrapper(Rectangle rectangle)
+ {
+ Rectangle = rectangle;
}
}
- private sealed class SizeWrapper {
+
+ private sealed class SizeWrapper
+ {
public Size Size;
- public SizeWrapper(Size size){
- this.Size = size;
+
+ public SizeWrapper(Size size)
+ {
+ Size = size;
}
}
-
}
}