Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / CompMod / System / Collections / Generic / ThrowHelper.cs / 1 / ThrowHelper.cs
namespace System { // This file defines an internal class used to throw exceptions in BCL code. // The main purpose is to reduce code size. // // The old way to throw an exception generates quite a lot IL code and assembly code. // Following is an example: // C# source // throw new ArgumentNullException("key", SR.GetString("ArgumentNull_Key")); // IL code: // IL_0003: ldstr "key" // IL_0008: ldstr "ArgumentNull_Key" // IL_000d: call string System.Environment::GetResourceString(string) // IL_0012: newobj instance void System.ArgumentNullException::.ctor(string,string) // IL_0017: throw // which is 21bytes in IL. // // So we want to get rid of the ldstr and call to Environment.GetResource in IL. // In order to do that, I created two enums: ExceptionResource, ExceptionArgument to represent the // argument name and resource name in a small integer. The source code will be changed to // ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key, ExceptionResource.ArgumentNull_Key); // // The IL code will be 7 bytes. // IL_0008: ldc.i4.4 // IL_0009: ldc.i4.4 // IL_000a: call void System.ThrowHelper::ThrowArgumentNullException(valuetype System.ExceptionArgument) // IL_000f: ldarg.0 // // This will also reduce the Jitted code size a lot. // // It is very important we do this for generic classes because we can easily generate the same code // multiple times for different instantiation. // //// Jit will generates the code to throw exception at the end of a method, thus we can reduce working // set if the user code will never throw an exception. However Jit doesn't know anything about the // methods in ThrowHelper, so it will not moves the instructions to the end. // This is not a problem for ngened code because we will probably move the code based on profile data(hopefully.) // // For jitted code, it doesn't make much difference. The only advantage of moving the code to the end is to // improve cache locality. Patrick pointed out this doesn't make much different on newer processor like P4. // using System.Runtime.Serialization; using System.Diagnostics; internal static class ThrowHelper { internal static void ThrowWrongKeyTypeArgumentException(object key, Type targetType) { throw new ArgumentException(SR.GetString(SR.Arg_WrongType, key, targetType), "key"); } internal static void ThrowWrongValueTypeArgumentException(object value, Type targetType) { throw new ArgumentException(SR.GetString(SR.Arg_WrongType, value, targetType), "value"); } internal static void ThrowKeyNotFoundException() { throw new System.Collections.Generic.KeyNotFoundException(); } internal static void ThrowArgumentException(ExceptionResource resource) { throw new ArgumentException(SR.GetString(GetResourceName(resource))); } internal static void ThrowArgumentNullException(ExceptionArgument argument) { throw new ArgumentNullException(GetArgumentName(argument)); } internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument) { throw new ArgumentOutOfRangeException(GetArgumentName(argument)); } internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) { throw new ArgumentOutOfRangeException(GetArgumentName(argument), SR.GetString(GetResourceName(resource))); } internal static void ThrowInvalidOperationException(ExceptionResource resource) { throw new InvalidOperationException(SR.GetString(GetResourceName(resource))); } internal static void ThrowSerializationException(ExceptionResource resource) { throw new SerializationException(SR.GetString(GetResourceName(resource))); } internal static void ThrowNotSupportedException(ExceptionResource resource) { throw new NotSupportedException(SR.GetString(GetResourceName(resource))); } // // This function will convert an ExceptionArgument enum value to the argument name string. // internal static string GetArgumentName(ExceptionArgument argument) { string argumentName = null; switch (argument) { case ExceptionArgument.array: argumentName = "array"; break; case ExceptionArgument.arrayIndex: argumentName = "arrayIndex"; break; case ExceptionArgument.capacity: argumentName = "capacity"; break; case ExceptionArgument.collection: argumentName = "collection"; break; case ExceptionArgument.converter: argumentName = "converter"; break; case ExceptionArgument.count: argumentName = "count"; break; case ExceptionArgument.dictionary: argumentName = "dictionary"; break; case ExceptionArgument.index: argumentName = "index"; break; case ExceptionArgument.info: argumentName = "info"; break; case ExceptionArgument.key: argumentName = "key"; break; case ExceptionArgument.match: argumentName = "match"; break; case ExceptionArgument.obj: argumentName = "obj"; break; case ExceptionArgument.queue: argumentName = "queue"; break; case ExceptionArgument.stack: argumentName = "stack"; break; case ExceptionArgument.startIndex: argumentName = "startIndex"; break; case ExceptionArgument.value: argumentName = "value"; break; default: Debug.Assert(false, "The enum value is not defined, please checked ExceptionArgumentName Enum."); return string.Empty; } return argumentName; } // // This function will convert an ExceptionResource enum value to the resource string. // internal static string GetResourceName(ExceptionResource resource) { string resourceName = null; switch (resource) { case ExceptionResource.Argument_ImplementIComparable: resourceName = SR.Argument_ImplementIComparable; break; case ExceptionResource.Argument_AddingDuplicate: resourceName = SR.Argument_AddingDuplicate; break; case ExceptionResource.ArgumentOutOfRange_Index: resourceName = SR.ArgumentOutOfRange_Index; break; case ExceptionResource.ArgumentOutOfRange_NeedNonNegNum: resourceName = SR.ArgumentOutOfRange_NeedNonNegNum; break; case ExceptionResource.ArgumentOutOfRange_NeedNonNegNumRequired: resourceName = SR.ArgumentOutOfRange_NeedNonNegNumRequired; break; case ExceptionResource.ArgumentOutOfRange_SmallCapacity: resourceName = SR.ArgumentOutOfRange_SmallCapacity; break; case ExceptionResource.Arg_ArrayPlusOffTooSmall: resourceName = SR.Arg_ArrayPlusOffTooSmall; break; case ExceptionResource.Arg_RankMultiDimNotSupported: resourceName = SR.Arg_MultiRank; break; case ExceptionResource.Arg_NonZeroLowerBound: resourceName = SR.Arg_NonZeroLowerBound; break; case ExceptionResource.Argument_InvalidArrayType: resourceName = SR.Invalid_Array_Type; break; case ExceptionResource.Argument_InvalidOffLen: resourceName = SR.Argument_InvalidOffLen; break; case ExceptionResource.InvalidOperation_CannotRemoveFromStackOrQueue: resourceName = SR.InvalidOperation_CannotRemoveFromStackOrQueue; break; case ExceptionResource.InvalidOperation_EmptyCollection: resourceName = SR.InvalidOperation_EmptyCollection; break; case ExceptionResource.InvalidOperation_EmptyQueue: resourceName = SR.InvalidOperation_EmptyQueue; break; case ExceptionResource.InvalidOperation_EnumOpCantHappen: resourceName = SR.InvalidOperation_EnumOpCantHappen; break; case ExceptionResource.InvalidOperation_EnumFailedVersion: resourceName = SR.InvalidOperation_EnumFailedVersion; break; case ExceptionResource.InvalidOperation_EmptyStack: resourceName = SR.InvalidOperation_EmptyStack; break; case ExceptionResource.InvalidOperation_EnumNotStarted: resourceName = SR.InvalidOperation_EnumNotStarted; break; case ExceptionResource.InvalidOperation_EnumEnded: resourceName = SR.InvalidOperation_EnumEnded; break; case ExceptionResource.NotSupported_KeyCollectionSet: resourceName = SR.NotSupported_KeyCollectionSet; break; case ExceptionResource.NotSupported_SortedListNestedWrite: resourceName = SR.NotSupported_SortedListNestedWrite; break; case ExceptionResource.Serialization_InvalidOnDeser: resourceName = SR.Serialization_InvalidOnDeser; break; case ExceptionResource.Serialization_MissingValues: resourceName = SR.Serialization_MissingValues; break; case ExceptionResource.Serialization_MismatchedCount: resourceName = SR.Serialization_MismatchedCount; break; case ExceptionResource.NotSupported_ValueCollectionSet: resourceName = SR.NotSupported_ValueCollectionSet; break; default: Debug.Assert(false, "The enum value is not defined, please checked ExceptionArgumentName Enum."); return string.Empty; } return resourceName; } } // // The convention for this enum is using the argument name as the enum name // internal enum ExceptionArgument { obj, dictionary, array, info, key, collection, match, converter, queue, stack, capacity, index, startIndex, value, count, arrayIndex, } // // The convention for this enum is using the resource name as the enum name // internal enum ExceptionResource { Argument_ImplementIComparable, ArgumentOutOfRange_NeedNonNegNum, ArgumentOutOfRange_NeedNonNegNumRequired, Arg_ArrayPlusOffTooSmall, Argument_AddingDuplicate, Serialization_InvalidOnDeser, Serialization_MismatchedCount, Serialization_MissingValues, Arg_RankMultiDimNotSupported, Arg_NonZeroLowerBound, Argument_InvalidArrayType, NotSupported_KeyCollectionSet, ArgumentOutOfRange_SmallCapacity, ArgumentOutOfRange_Index, Argument_InvalidOffLen, NotSupported_ReadOnlyCollection, InvalidOperation_CannotRemoveFromStackOrQueue, InvalidOperation_EmptyCollection, InvalidOperation_EmptyQueue, InvalidOperation_EnumOpCantHappen, InvalidOperation_EnumFailedVersion, InvalidOperation_EmptyStack, InvalidOperation_EnumNotStarted, InvalidOperation_EnumEnded, NotSupported_SortedListNestedWrite, NotSupported_ValueCollectionSet, } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. namespace System { // This file defines an internal class used to throw exceptions in BCL code. // The main purpose is to reduce code size. // // The old way to throw an exception generates quite a lot IL code and assembly code. // Following is an example: // C# source // throw new ArgumentNullException("key", SR.GetString("ArgumentNull_Key")); // IL code: // IL_0003: ldstr "key" // IL_0008: ldstr "ArgumentNull_Key" // IL_000d: call string System.Environment::GetResourceString(string) // IL_0012: newobj instance void System.ArgumentNullException::.ctor(string,string) // IL_0017: throw // which is 21bytes in IL. // // So we want to get rid of the ldstr and call to Environment.GetResource in IL. // In order to do that, I created two enums: ExceptionResource, ExceptionArgument to represent the // argument name and resource name in a small integer. The source code will be changed to // ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key, ExceptionResource.ArgumentNull_Key); // // The IL code will be 7 bytes. // IL_0008: ldc.i4.4 // IL_0009: ldc.i4.4 // IL_000a: call void System.ThrowHelper::ThrowArgumentNullException(valuetype System.ExceptionArgument) // IL_000f: ldarg.0 // // This will also reduce the Jitted code size a lot. // // It is very important we do this for generic classes because we can easily generate the same code // multiple times for different instantiation. // //// Jit will generates the code to throw exception at the end of a method, thus we can reduce working // set if the user code will never throw an exception. However Jit doesn't know anything about the // methods in ThrowHelper, so it will not moves the instructions to the end. // This is not a problem for ngened code because we will probably move the code based on profile data(hopefully.) // // For jitted code, it doesn't make much difference. The only advantage of moving the code to the end is to // improve cache locality. Patrick pointed out this doesn't make much different on newer processor like P4. // using System.Runtime.Serialization; using System.Diagnostics; internal static class ThrowHelper { internal static void ThrowWrongKeyTypeArgumentException(object key, Type targetType) { throw new ArgumentException(SR.GetString(SR.Arg_WrongType, key, targetType), "key"); } internal static void ThrowWrongValueTypeArgumentException(object value, Type targetType) { throw new ArgumentException(SR.GetString(SR.Arg_WrongType, value, targetType), "value"); } internal static void ThrowKeyNotFoundException() { throw new System.Collections.Generic.KeyNotFoundException(); } internal static void ThrowArgumentException(ExceptionResource resource) { throw new ArgumentException(SR.GetString(GetResourceName(resource))); } internal static void ThrowArgumentNullException(ExceptionArgument argument) { throw new ArgumentNullException(GetArgumentName(argument)); } internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument) { throw new ArgumentOutOfRangeException(GetArgumentName(argument)); } internal static void ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) { throw new ArgumentOutOfRangeException(GetArgumentName(argument), SR.GetString(GetResourceName(resource))); } internal static void ThrowInvalidOperationException(ExceptionResource resource) { throw new InvalidOperationException(SR.GetString(GetResourceName(resource))); } internal static void ThrowSerializationException(ExceptionResource resource) { throw new SerializationException(SR.GetString(GetResourceName(resource))); } internal static void ThrowNotSupportedException(ExceptionResource resource) { throw new NotSupportedException(SR.GetString(GetResourceName(resource))); } // // This function will convert an ExceptionArgument enum value to the argument name string. // internal static string GetArgumentName(ExceptionArgument argument) { string argumentName = null; switch (argument) { case ExceptionArgument.array: argumentName = "array"; break; case ExceptionArgument.arrayIndex: argumentName = "arrayIndex"; break; case ExceptionArgument.capacity: argumentName = "capacity"; break; case ExceptionArgument.collection: argumentName = "collection"; break; case ExceptionArgument.converter: argumentName = "converter"; break; case ExceptionArgument.count: argumentName = "count"; break; case ExceptionArgument.dictionary: argumentName = "dictionary"; break; case ExceptionArgument.index: argumentName = "index"; break; case ExceptionArgument.info: argumentName = "info"; break; case ExceptionArgument.key: argumentName = "key"; break; case ExceptionArgument.match: argumentName = "match"; break; case ExceptionArgument.obj: argumentName = "obj"; break; case ExceptionArgument.queue: argumentName = "queue"; break; case ExceptionArgument.stack: argumentName = "stack"; break; case ExceptionArgument.startIndex: argumentName = "startIndex"; break; case ExceptionArgument.value: argumentName = "value"; break; default: Debug.Assert(false, "The enum value is not defined, please checked ExceptionArgumentName Enum."); return string.Empty; } return argumentName; } // // This function will convert an ExceptionResource enum value to the resource string. // internal static string GetResourceName(ExceptionResource resource) { string resourceName = null; switch (resource) { case ExceptionResource.Argument_ImplementIComparable: resourceName = SR.Argument_ImplementIComparable; break; case ExceptionResource.Argument_AddingDuplicate: resourceName = SR.Argument_AddingDuplicate; break; case ExceptionResource.ArgumentOutOfRange_Index: resourceName = SR.ArgumentOutOfRange_Index; break; case ExceptionResource.ArgumentOutOfRange_NeedNonNegNum: resourceName = SR.ArgumentOutOfRange_NeedNonNegNum; break; case ExceptionResource.ArgumentOutOfRange_NeedNonNegNumRequired: resourceName = SR.ArgumentOutOfRange_NeedNonNegNumRequired; break; case ExceptionResource.ArgumentOutOfRange_SmallCapacity: resourceName = SR.ArgumentOutOfRange_SmallCapacity; break; case ExceptionResource.Arg_ArrayPlusOffTooSmall: resourceName = SR.Arg_ArrayPlusOffTooSmall; break; case ExceptionResource.Arg_RankMultiDimNotSupported: resourceName = SR.Arg_MultiRank; break; case ExceptionResource.Arg_NonZeroLowerBound: resourceName = SR.Arg_NonZeroLowerBound; break; case ExceptionResource.Argument_InvalidArrayType: resourceName = SR.Invalid_Array_Type; break; case ExceptionResource.Argument_InvalidOffLen: resourceName = SR.Argument_InvalidOffLen; break; case ExceptionResource.InvalidOperation_CannotRemoveFromStackOrQueue: resourceName = SR.InvalidOperation_CannotRemoveFromStackOrQueue; break; case ExceptionResource.InvalidOperation_EmptyCollection: resourceName = SR.InvalidOperation_EmptyCollection; break; case ExceptionResource.InvalidOperation_EmptyQueue: resourceName = SR.InvalidOperation_EmptyQueue; break; case ExceptionResource.InvalidOperation_EnumOpCantHappen: resourceName = SR.InvalidOperation_EnumOpCantHappen; break; case ExceptionResource.InvalidOperation_EnumFailedVersion: resourceName = SR.InvalidOperation_EnumFailedVersion; break; case ExceptionResource.InvalidOperation_EmptyStack: resourceName = SR.InvalidOperation_EmptyStack; break; case ExceptionResource.InvalidOperation_EnumNotStarted: resourceName = SR.InvalidOperation_EnumNotStarted; break; case ExceptionResource.InvalidOperation_EnumEnded: resourceName = SR.InvalidOperation_EnumEnded; break; case ExceptionResource.NotSupported_KeyCollectionSet: resourceName = SR.NotSupported_KeyCollectionSet; break; case ExceptionResource.NotSupported_SortedListNestedWrite: resourceName = SR.NotSupported_SortedListNestedWrite; break; case ExceptionResource.Serialization_InvalidOnDeser: resourceName = SR.Serialization_InvalidOnDeser; break; case ExceptionResource.Serialization_MissingValues: resourceName = SR.Serialization_MissingValues; break; case ExceptionResource.Serialization_MismatchedCount: resourceName = SR.Serialization_MismatchedCount; break; case ExceptionResource.NotSupported_ValueCollectionSet: resourceName = SR.NotSupported_ValueCollectionSet; break; default: Debug.Assert(false, "The enum value is not defined, please checked ExceptionArgumentName Enum."); return string.Empty; } return resourceName; } } // // The convention for this enum is using the argument name as the enum name // internal enum ExceptionArgument { obj, dictionary, array, info, key, collection, match, converter, queue, stack, capacity, index, startIndex, value, count, arrayIndex, } // // The convention for this enum is using the resource name as the enum name // internal enum ExceptionResource { Argument_ImplementIComparable, ArgumentOutOfRange_NeedNonNegNum, ArgumentOutOfRange_NeedNonNegNumRequired, Arg_ArrayPlusOffTooSmall, Argument_AddingDuplicate, Serialization_InvalidOnDeser, Serialization_MismatchedCount, Serialization_MissingValues, Arg_RankMultiDimNotSupported, Arg_NonZeroLowerBound, Argument_InvalidArrayType, NotSupported_KeyCollectionSet, ArgumentOutOfRange_SmallCapacity, ArgumentOutOfRange_Index, Argument_InvalidOffLen, NotSupported_ReadOnlyCollection, InvalidOperation_CannotRemoveFromStackOrQueue, InvalidOperation_EmptyCollection, InvalidOperation_EmptyQueue, InvalidOperation_EnumOpCantHappen, InvalidOperation_EnumFailedVersion, InvalidOperation_EmptyStack, InvalidOperation_EnumNotStarted, InvalidOperation_EnumEnded, NotSupported_SortedListNestedWrite, NotSupported_ValueCollectionSet, } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- LoginViewDesigner.cs
- FontDifferentiator.cs
- AutomationPattern.cs
- ColorContextHelper.cs
- SafeTimerHandle.cs
- XmlSerializationGeneratedCode.cs
- ListViewPagedDataSource.cs
- DrawingCollection.cs
- DefaultObjectMappingItemCollection.cs
- BackgroundWorker.cs
- ProjectionCamera.cs
- CalendarDesigner.cs
- Regex.cs
- WindowsRichEdit.cs
- RubberbandSelector.cs
- CommonDialog.cs
- XmlQueryTypeFactory.cs
- ScrollContentPresenter.cs
- ReferenceEqualityComparer.cs
- ScrollBarAutomationPeer.cs
- Column.cs
- OleDbTransaction.cs
- ChannelDispatcherBase.cs
- RightNameExpirationInfoPair.cs
- ItemDragEvent.cs
- OperandQuery.cs
- CodeGotoStatement.cs
- _SingleItemRequestCache.cs
- AutomationElementIdentifiers.cs
- CodeDirectiveCollection.cs
- ListChangedEventArgs.cs
- AdapterUtil.cs
- SystemBrushes.cs
- Expression.cs
- WFItemsToSpacerVisibility.cs
- ToolStripRenderEventArgs.cs
- SamlDoNotCacheCondition.cs
- AmbientProperties.cs
- ValueTable.cs
- WeakReferenceEnumerator.cs
- SmtpTransport.cs
- JsonQNameDataContract.cs
- PrintPreviewControl.cs
- ProfileSection.cs
- ButtonField.cs
- ToolStripManager.cs
- _ContextAwareResult.cs
- FaultCallbackWrapper.cs
- Focus.cs
- TripleDESCryptoServiceProvider.cs
- IteratorDescriptor.cs
- ValidationErrorCollection.cs
- PenThreadWorker.cs
- UpDownBase.cs
- FontFaceLayoutInfo.cs
- ClientSettingsProvider.cs
- DigitalSignatureProvider.cs
- MeshGeometry3D.cs
- BooleanConverter.cs
- XmlDataLoader.cs
- QuaternionRotation3D.cs
- TransactionManagerProxy.cs
- WindowsSolidBrush.cs
- ListItemViewAttribute.cs
- RichTextBox.cs
- CompositeTypefaceMetrics.cs
- UnsafeNetInfoNativeMethods.cs
- SmtpCommands.cs
- UserInitiatedRoutedEventPermissionAttribute.cs
- BaseCodePageEncoding.cs
- PersonalizationStateInfoCollection.cs
- SessionEndingCancelEventArgs.cs
- EnumMember.cs
- HandleCollector.cs
- DataRelation.cs
- BoundColumn.cs
- FontSourceCollection.cs
- SqlConnectionString.cs
- Stroke.cs
- ExceptionWrapper.cs
- PageTheme.cs
- XmlBaseWriter.cs
- SpeechUI.cs
- SoapAttributeOverrides.cs
- StreamMarshaler.cs
- FamilyCollection.cs
- HybridWebProxyFinder.cs
- GridItem.cs
- PersonalizationProviderHelper.cs
- NativeMethods.cs
- SpStreamWrapper.cs
- localization.cs
- ToolStripDropDownButton.cs
- ConfigurationPropertyAttribute.cs
- AccessKeyManager.cs
- AutomationAttributeInfo.cs
- TypeConverterBase.cs
- HtmlShim.cs
- ServerIdentity.cs
- NavigationPropertyAccessor.cs