} // AllASCIICharacters #endregion // Instance Properties #region Private Instance Methods /// <summary> /// Since the class is a singleton, I separated the initializer from the /// constructor, as has been my custom. /// </summary> private void InitialzeInstance ( ) { const int ASCII_CHARACTER_COUNT = 256; const string ASCII_TABLE_SOURCE = @"ASCII_Character_Display_Table.TSV"; // ---------------------------------------------------------------- // The expected row count is one greater than the number of ASCII // characters because the first row in the table contains column // labels. // // As a sanity check, the label row is compared against a constant, // LABEL_ROW. // ---------------------------------------------------------------- const int EXPECTED_ROW_COUNT = ASCII_CHARACTER_COUNT + ArrayInfo.ORDINAL_FROM_INDEX; //const int COL_CODE = 0; const int COL_CHARTYPE = 1; const int COL_SUBTYPE = 2; const int COL_CHAR = 3; const int COL_DESCRIPTION = 4; const int COL_HTML_NAME = 5; const int COL_DISPLAY = 6; const int COL_COMMENT = 7; const int COL_EXPECTED_COUNT = 8; const string LABEL_ROW = "Code\tCharType\tSubtype\tCHAR\tDESCRIPTION\tHTML Name\tDisplay\tComment"; string [ ] astrASCIITable = Readers.LoadTextFileFromCallingAssembly ( ASCII_TABLE_SOURCE ); if ( astrASCIITable.Length == EXPECTED_ROW_COUNT ) { _asciiTable = new ASCIICharacterDisplayInfo [ ASCII_CHARACTER_COUNT ]; for ( int intJ = ArrayInfo.ARRAY_FIRST_ELEMENT ; intJ < EXPECTED_ROW_COUNT ; intJ++ ) { if ( intJ == ArrayInfo.ARRAY_FIRST_ELEMENT ) { if ( astrASCIITable [ ArrayInfo.ARRAY_FIRST_ELEMENT ] != LABEL_ROW ) { // Verify that the label row is as expected. throw new Exception ( string.Format ( Properties.Resources.ERRMSG_BAD_LABEL_ROW , // Format Control String: Internal Table Error: The label row is invalid.{2}Expected label row = {0}{2}Actaul label row = {1} LABEL_ROW , // Format Item 0: Expected label row = {0} astrASCIITable [ ArrayInfo.ARRAY_FIRST_ELEMENT ] , // Format Item 1: Actaul label row = {1} Environment.NewLine ) ); // Format Item 2: Line break between message parts } // if ( astrASCIITable [ ArrayInfo.ARRAY_FIRST_ELEMENT ] != LABEL_ROW ) } // TRUE (This is the label row.) block, if ( intJ == ArrayInfo.ARRAY_FIRST_ELEMENT ) else { string [ ] astrFields = astrASCIITable [ intJ ].Split ( SpecialCharacters.TAB_CHAR ); if ( astrFields.Length == COL_EXPECTED_COUNT ) { int intCharacterCode = ArrayInfo.IndexFromOrdinal ( intJ ); _asciiTable [ intCharacterCode ] = new ASCIICharacterDisplayInfo ( ( uint ) intCharacterCode , // uint puintCode ( char ) intCharacterCode , // char pchrCharacter ( ASCIICharacterDisplayInfo.CharacterType ) Enum.Parse ( // CharacterType penmCharacterType typeof ( ASCIICharacterDisplayInfo.CharacterType ) , // Type enumType astrFields [ COL_CHARTYPE ] , // string value true ) , // bool ignoreCase ( ASCIICharacterDisplayInfo.CharacterSubtype ) Enum.Parse ( // CharacterType penmCharacterType typeof ( ASCIICharacterDisplayInfo.CharacterSubtype ) , // Type enumType astrFields [ COL_SUBTYPE ] , // string value true ) , // bool ignoreCase astrFields [ COL_CHAR ] , // string pstrCHAR astrFields [ COL_DESCRIPTION ] , // string pstrDescription astrFields [ COL_HTML_NAME ] , // string pstrHTMLName astrFields [ COL_DISPLAY ] , // string pstrAlternateText astrFields [ COL_COMMENT ] ); // string pstrComment } // TRUE (anticipated outcome) block, if ( astrFields.Length == COL_EXPECTED_COUNT ) else { throw new Exception ( string.Format ( Properties.Resources.ERRMSG_BAD_DETAIL_ROW ,// Format Control String: Internal Table Error: Detaill row {0} is invalid.{3}Expected field count = {1}{3}Actaul field count = {2} intJ , // Format Item 0: Detaill row {0} is invalid. COL_EXPECTED_COUNT , // Format Item 1: Expected field count = {1} astrFields.Length , // Format Item 2: Actaul field count = {2} Environment.NewLine ) ); // Format Item 3: Line Break } // FALSE (unanticipated outcome) block, if ( astrFields.Length == COL_EXPECTED_COUNT ) } // FALSE (This is a detail row.) block, if ( intJ == ArrayInfo.ARRAY_FIRST_ELEMENT ) } // for ( int intJ = ArrayInfo.ARRAY_FIRST_ELEMENT ; intJ < EXPECTED_ROW_COUNT ; intJ++ ) } // TRUE (anticipated outcome) block, if ( astrASCIITable.Length == EXPECTED_ROW_COUNT ) else { throw new Exception ( string.Format ( Properties.Resources.ERRMSG_UNEXPECTED_ROW_COUNT , // Format Control String: Internal Table Error: The ASCII Table should contain {0} rows. Instead, it contains {1} rows. EXPECTED_ROW_COUNT , // Format Item 0: The ASCII Table should contain {0} rows. astrASCIITable.Length ) ); // Format Item 1: Instead, it contains {1} rows. } // FALSE (unanticipated outcome) block, if ( astrASCIITable.Length == EXPECTED_ROW_COUNT ) } // InitialzeInstance
} // void ListObjectProperties /// <summary> /// Enumerate the properties of an object, showing for each its type and /// value, as a formatted listing. /// </summary> /// <param name="pstrNameOfObject"> /// Name of object as it appears in the calling routine /// </param> /// <param name="pObjThisOne"> /// Reference to the object from which to enumerate properties /// </param> /// <param name="pintLeftPadding"> /// Optional left padding for the report /// </param> /// <param name="pstrObjectLabelSuffix"> /// Optional supplementary label information for the object /// </param> /// <param name="penmBindingFlags"> /// Binding flags mask, which determines which properties are enumerated /// </param> public static void ListObjectPropertyTypesAndValues ( string pstrNameOfObject, object pObjThisOne, int pintLeftPadding = ListInfo.EMPTY_STRING_LENGTH, string pstrObjectLabelSuffix = null, BindingFlags penmBindingFlags = DEFAULT_BINDING_FLAGS ) { string strIndentation = pintLeftPadding > ListInfo.EMPTY_STRING_LENGTH ? StringTricks.StrFill ( SpecialCharacters.SPACE_CHAR , pintLeftPadding ) : SpecialStrings.EMPTY_STRING; PropertyInfo [ ] apropertyInfos = pObjThisOne.GetType ( ).GetProperties ( penmBindingFlags ); int intMaxDigits = apropertyInfos.Length.ToString ( ).Length; // Compute the width of the largest possible ordinal. Console.WriteLine ( Properties.Resources.MSG_PROPERTY_LIST_HEADER , // Format Control String strIndentation , // Format Item 0: {0}Object pstrNameOfObject , // Format Item 1: Object {1} pstrObjectLabelSuffix == null // Format Item 2: {2} exposes the ? SpecialStrings.EMPTY_STRING // when pstrObjectLabelSuffix == null : $" ({pstrObjectLabelSuffix})" , // when pstrObjectLabelSuffix != null apropertyInfos.Length , // Format Item 3: exposes the following {2} Environment.NewLine ); // Format Item 4: public properties:{4} for ( int intPropertyIndex = ArrayInfo.ARRAY_FIRST_ELEMENT ; intPropertyIndex < apropertyInfos.Length ; intPropertyIndex++ ) { try { Console.WriteLine ( Properties.Resources.MSG_PROP_TYPE_AND_VALUE_DETAIL , // Format Control String strIndentation , // Format Item 0: {0}Property NumericFormats.FormatIntegerLeftPadded ( // Format Item 1: Property {1}: ArrayInfo.OrdinalFromIndex ( // Get the ordinal equivalent to array subscript. intPropertyIndex ) , // Array subscript for which to get the corresponding ordinal. intMaxDigits ) , // Right align to this width. apropertyInfos [ intPropertyIndex ].Name , // Format Item 2: : {2} apropertyInfos[intPropertyIndex].PropertyType.FullName ,// Format Item 3: ({3}) = StringTricks.TruncateValueToOneLine ( // Format Item 4: = {4} apropertyInfos [ intPropertyIndex ].GetValue ( // Get value from the apropertyInfos in array slot intPropertyIndex. pObjThisOne , // Object from which to get property value. null ) ) ); // The null CultureInfo causes the method to infer the culture of the calling thread. } catch ( TargetInvocationException ex ) { Console.WriteLine ( Properties.Resources.ERRMSG_PROPERTY_LIST , // Format Control String strIndentation , // Format Item 0: {0}Property ArrayInfo.OrdinalFromIndex ( intPropertyIndex ) , // Format Item 1: Property {1}: apropertyInfos [ intPropertyIndex ].Name , // Format Item 2: : {2} = ex.Message ); // Format Item 3: = {3} } } // for ( int intPropertyIndex = ArrayInfo.ARRAY_FIRST_ELEMENT ; intPropertyIndex < apropertyInfos.Length ; intPropertyIndex++ ) Console.WriteLine ( Properties.Resources.MSG_PROPERTY_LIST_FOOTER , // Format Control String strIndentation , // Format Item 0 Environment.NewLine ); // Format Item 1 } // void ListObjectPropertyTypesAndValues