System.String 类的实现代码

// ==++==
//
//  
//   Copyright (c) 2002 Microsoft Corporation. All rights reserved.
//  
//   The use and distribution terms for this software are contained in the file
//   named license.txt, which can be found in the root of this distribution.
//   By using this software in any fashion, you are agreeing to be bound by the
//   terms of this license.
//  
//   You must not remove this notice, or any other, from this software.
//  
//
// ==--==
/**//*============================================================
**
** Class: String
**
**                          
**
** Purpose: Contains headers for the String class. Actual implementations
** are in String.cpp
**
** Date: March 15, 1998
**
===========================================================*/
namespace System ...{
  using System.Text;
  using System;
  using System.Globalization;
  using System.Threading;
  using System.Collections;
  using System.Runtime.CompilerServices;
  using va_list = System.ArgIterator;
  using __UnmanagedMemoryStream = System.IO.__UnmanagedMemoryStream;
  //
  // For Information on these methods, please see COMString.cpp
  //
  // The String class represents a static string of characters. Many of
  // the String methods perform some type of transformation on the current
  // instance and return the result as a new String. All comparison methods are
  // implemented as a part of String. As with arrays, character positions
  // (indices) are zero-based.
  //
  // When passing a null string into a constructor in VJ and VC, the null should be
  // explicitly type cast to a String.
  // For Example:
  // String s = new String((String)null);
  // Text.Out.WriteLine(s);
  //
  /**////
  [Serializable] public sealed class String : IComparable, ICloneable, IConvertible, IEnumerable ...{
   
    //
    //NOTE NOTE NOTE NOTE
    //These fields map directly onto the fields in an EE StringObject. See object.h for the layout.
    //
    [NonSerialized]private int m_arrayLength;
    [NonSerialized]private int m_stringLength;
    [NonSerialized]private char m_firstChar;

    //private static readonly char FmtMsgMarkerChar='%';
    //private static readonly char FmtMsgFmtCodeChar='!';
    //These are defined in Com99/src/vm/COMStringCommon.h and must be kept in sync.
    private const int TrimHead = 0;
    private const int TrimTail = 1;
    private const int TrimBoth = 2;
 
    // The Empty constant holds the empty string value.
    //We need to call the String constructor so that the compiler doesn't mark this as a literal.
    //Marking this as a literal would mean that it doesn't show up as a field which we can access
    //from native.
    /**////
    public static readonly String Empty = "";
 
    //
    //Native Static Methods
    //
 
    // Joins an array of strings together as one string with a separator between each original string.
    //
    /**////
    public static String Join (String separator, String[] value) ...{
        if (value==null) ...{
          throw new ArgumentNullException("value");
        }
        return Join(separator, value, 0, value.Length);
    }
 
    // Joins an array of strings together as one string with a separator between each original string.
    //
    /**////
    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    public static extern String Join (String separator, String[] value, int startIndex, int count);
 
    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    internal static extern int nativeCompareOrdinal(String strA, String strB, bool bIgnoreCase);

    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    internal static extern int nativeCompareOrdinalEx(String strA, int indexA, String strB, int indexB, int count);
    //This will not work in case-insensitive mode for any character greater than 0x80.
    //We'll throw an ArgumentException.
    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    unsafe internal static extern int nativeCompareOrdinalWC(String strA, char *strBChars, bool bIgnoreCase, out bool success);


    //
    // This is a helper method for the security team. They need to uppercase some strings (guaranteed to be less
    // than 0x80) before security is fully initialized. Without security initialized, we can't grab resources (the nlp's)
    // from the assembly. This provides a workaround for that problem and should NOT be used anywhere else.
    //
    internal static String SmallCharToUpper(String strA) ...{
        String newString = FastAllocateString(strA.Length);
        nativeSmallCharToUpper(strA, newString);
        return newString;
    }

    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    private static extern void nativeSmallCharToUpper(String strIn, String strOut);

    // This is a helper method for the security team. They need to construct strings from a char[]
    // within their homebrew XML parser. They guarantee that the char[] they pass in isn't null and
    // that the provided indices are valid so we just stuff real fast.
    internal static String CreateFromCharArray( char[] array, int start, int count )
    ...{
        String newString = FastAllocateString( count );
        FillStringArray( newString, 0, array, start, count );
        return newString;
    }

    //
    //
    // NATIVE INSTANCE METHODS
    //
    //
 
    //
    // Search/Query methods
    //
 
    // Determines whether two strings match.
    /**////
    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    public extern override bool Equals(Object obj);
 
    // Determines whether two strings match.
    /**////
    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    public extern bool Equals(String value);
 
    // Determines whether two Strings match.
    /**////
    public static bool Equals(String a, String b) ...{
        if ((Object)a==(Object)b) ...{
          return true;
        }
 
        if ((Object)a==null || (Object)b==null) ...{
          return false;
        }
 
        return a.Equals(b);
    }

    /**////
    public static bool operator == (String a, String b) ...{
      return String.Equals(a, b);
    }

    /**////
    public static bool operator != (String a, String b) ...{
      return !String.Equals(a, b);
    }

    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    internal extern char InternalGetChar(int index);
 
    // Gets the character at a specified position.
    //
    /**////
    [System.Runtime.CompilerServices.IndexerName("Chars")]
    public char this[int index] ...{
        get ...{ return InternalGetChar(index); }
    }

    // Converts a substring of this string to an array of characters. Copies the
    // characters of this string beginning at position startIndex and ending at
    // startIndex + length - 1 to the character array buffer, beginning
    // at bufferStartIndex.
    //
    /**////
    public void CopyTo(int sourceIndex, char[] destination, int destinationIndex, int count)
    ...{
        if (destination == null)
          throw new ArgumentNullException("destination");
        if (count < 0)
          throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NegativeCount"));
        if (sourceIndex < 0)
          throw new ArgumentOutOfRangeException("sourceIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
        if (count > Length - sourceIndex)
          throw new ArgumentOutOfRangeException("sourceIndex", Environment.GetResourceString("ArgumentOutOfRange_IndexCount"));
        if (destinationIndex > destination.Length-count || destinationIndex < 0)
          throw new ArgumentOutOfRangeException("destinationIndex", Environment.GetResourceString("ArgumentOutOfRange_IndexCount"));
        InternalCopyTo(sourceIndex, destination, destinationIndex, count);
    }

    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    internal extern void InternalCopyTo(int sourceIndex, char[] destination, int destinationIndex, int count);
 
    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    internal extern void CopyToByteArray(int sourceIndex, byte[] destination, int destinationIndex, int charCount);
 
    // Returns the entire string as an array of characters.
    /**////
    public char[] ToCharArray() ...{
        return ToCharArray(0,Length);
    }
 
    // Returns a substring of this string as an array of characters.
    //
    /**////
    public char[] ToCharArray(int startIndex, int length)
    ...{
        // Range check everything.
        if (startIndex < 0 || startIndex > Length || startIndex > Length - length)
          throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_Index"));
        if (length < 0)
          throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_Index"));

        char[] chars = new char[length];
        InternalCopyTo(startIndex, chars, 0, length);
        return chars;
    }
 
    // Gets a hash code for this string. If strings A and B are such that A.Equals(B), then
    // they will return the same hash code.
    /**////
    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    public extern override int GetHashCode();
 
    // Gets the length of this string
    /**////
    public int Length ...{
        get ...{ return InternalLength(); }
    }
 
    /**//// This is a EE implemented function so that the JIT can recognise is specially
    /// and eliminate checks on character fetchs.
    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    private extern int InternalLength();
 
    /**////
    internal int ArrayLength ...{
        get ...{ return (m_arrayLength); }
    }

    // Used by StringBuilder
    internal int Capacity ...{
        get ...{ return (m_arrayLength - 1); }
    }

    // Creates an array of strings by splitting this string at each
    // occurence of a separator. The separator is searched for, and if found,
    // the substring preceding the occurence is stored as the first element in
    // the array of strings. We then continue in this manner by searching
    // the substring that follows the occurence. On the other hand, if the separator
    // is not found, the array of strings will contain this instance as its only element.
    // If the separator is null
    // whitespace (i.e., Character.IsWhitespace) is used as the separator.
    //
    /**////
    public String [] Split(params char [] separator) ...{
        return Split(separator, Int32.MaxValue);
    }
 
    // Creates an array of strings by splitting this string at each
    // occurence of a separator. The separator is searched for, and if found,
    // the substring preceding the occurence is stored as the first element in
    // the array of strings. We then continue in this manner by searching
    // the substring that follows the occurence. On the other hand, if the separator
    // is not found, the array of strings will contain this instance as its only element.
    // If the spearator is the empty string (i.e., String.Empty), then
    // whitespace (i.e., Character.IsWhitespace) is used as the separator.
    // If there are more than count different strings, the last n-(count-1)
    // elements are concatenated and added as the last String.
    //
    /**////
    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    public extern String[] Split(char[] separator, int count);
 
 
    // Returns a substring of this string.
    //
    /**////
    public String Substring (int startIndex) ...{
        return this.Substring (startIndex, Length-startIndex);
    }
 
    // Returns a substring of this string.
    //
    /**////
    public String Substring (int startIndex, int length) ...{
       
        int thisLength = Length;
       
        //Bounds Checking.
        if (startIndex<0) ...{
          throw new ArgumentOutOfRangeException("startIndex", Environment.GetResourceString("ArgumentOutOfRange_StartIndex"));
        }

        if (length<0) ...{
          throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_NegativeLength"));
        }

        if (startIndex > thisLength-length) ...{
          throw new ArgumentOutOfRangeException("length", Environment.GetResourceString("ArgumentOutOfRange_IndexLength"));
        }

        String s = FastAllocateString(length);
        FillSubstring(s, 0, this, startIndex, length);

        return s;
    }
 
    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    internal extern String TrimHelper(char[] trimChars, int trimType);
 
    //This should really live on System.Globalization.CharacterInfo. However,
    //Trim gets called by security while resgen is running, so we can't run
    //CharacterInfo's class initializer (which goes to native and looks for a
    //resource table that hasn't yet been attached to the assembly when resgen
    //runs.
    internal static readonly char[] WhitespaceChars =  
        ...{ (char) 0x9, (char) 0xA, (char) 0xB, (char) 0xC, (char) 0xD, (char) 0x20, (char) 0xA0,
        (char) 0x2000, (char) 0x2001, (char) 0x2002, (char) 0x2003, (char) 0x2004, (char) 0x2005,
        (char) 0x2006, (char) 0x2007, (char) 0x2008, (char) 0x2009, (char) 0x200A, (char) 0x200B,
        (char) 0x3000, (char) 0xFEFF };
 
    // Removes a string of characters from the ends of this string.
    /**////
    public String Trim(params char[] trimChars) ...{
        if (null==trimChars || trimChars.Length == 0) ...{
          trimChars=WhitespaceChars;
        }
        return TrimHelper(trimChars,TrimBoth);
    }
 
    // Removes a string of characters from the beginning of this string.
    /**////
    public String TrimStart(params char[] trimChars) ...{
        if (null==trimChars || trimChars.Length == 0) ...{
          trimChars=WhitespaceChars;
        }
        return TrimHelper(trimChars,TrimHead);
    }
 
 
    // Removes a string of characters from the end of this string.
    /**////
    public String TrimEnd(params char[] trimChars) ...{
        if (null==trimChars || trimChars.Length == 0) ...{
          trimChars=WhitespaceChars;
        }
        return TrimHelper(trimChars,TrimTail);
    }
 
 
    // Creates a new string with the characters copied in from ptr. If
    // ptr is null, a string initialized to ";<;No Object>;"; (i.e.,
    // String.NullString) is created.
    //
    // Issue: This method is only accessible from VC.
    /**////
    [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
    unsafe public extern String(char *value);
    /**////
    [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
    unsafe public extern String(char *value, int startIndex, int length);
 
    /**////
    [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
    unsafe public extern String(sbyte *value);
    /**////
    [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
    unsafe public extern String(sbyte *value, int startIndex, int length);

    /**////
    [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
    unsafe public extern String(sbyte *value, int startIndex, int length, Encoding enc);
         
    unsafe static private String CreateString(sbyte *value, int startIndex, int length, Encoding enc) ...{
        if (enc == null)
          return new String(value, startIndex, length); // default to ANSI
        if (length < 0)
          throw new ArgumentOutOfRangeException("length",Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
        byte [] b = new byte[length];
        __UnmanagedMemoryStream.memcpy((byte*)value, startIndex, b, 0, length);
        return enc.GetString(b);
    }

    // For ASCIIEncoding::GetString()
    unsafe static internal String CreateStringFromASCII(byte[] bytes, int startIndex, int length) ...{
        BCLDebug.Assert(bytes != null, "need a byte[].");
        BCLDebug.Assert(startIndex >= 0 && (startIndex < bytes.Length || bytes.Length == 0), "startIndex >= 0 && startIndex < bytes.Length");
        BCLDebug.Assert(length >= 0 && length <= bytes.Length - startIndex, "length >= 0 && length <= bytes.Length - startIndex");
        if (length == 0)
          return String.Empty;
        String s = FastAllocateString(length);
        fixed(char* pChars = &s.m_firstChar) ...{
          for(int i=0; i             pChars
= (char) (bytes[i+startIndex] & 0x7f);
        }
        return s;
    }
 
    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    private extern static String FastAllocateString(int length);

    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    private extern static void FillString(String dest, int destPos, String src);

    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    private extern static void FillStringChecked(String dest, int destPos, String src);

    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    private extern static void FillStringEx(String dest, int destPos, String src,int srcLength);

    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    private extern static void FillStringArray(String dest, int stringStart, char[] array, int charStart, int count);

    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    private extern static void FillSubstring(String dest, int destPos, String src, int startPos, int count);


 
    // Creates a new string from the characters in a subarray. The new string will
    // be created from the characters in value between startIndex and
    // startIndex + length - 1.
    //
    /**////
    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    public extern String(char [] value, int startIndex, int length);
 
    // Creates a new string from the characters in a subarray. The new string will be
    // created from the characters in value.
    //
    /**////
    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    public extern String(char [] value);
 
    /**////
    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    public extern String(char c, int count);

 
    //
    //
    // INSTANCE METHODS
    //
    //
 
    // Provides a culture-correct string comparison. StrA is compared to StrB
    // to determine whether it is lexicographically less, equal, or greater, and then returns
    // either a negative integer, 0, or a positive integer; respectively.
    //
    /**////
    public static int Compare(String strA, String strB) ...{
        return CultureInfo.CurrentCulture.CompareInfo.Compare(strA, strB, CompareOptions.None);
    }
 
    // Provides a culture-correct string comparison. strA is compared to strB
    // to determine whether it is lexicographically less, equal, or greater, and then a
    // negative integer, 0, or a positive integer is returned; respectively.
    // The case-sensitive option is set by ignoreCase
    //
    /**////
    public static int Compare(String strA, String strB, bool ignoreCase) ...{
        if (ignoreCase) ...{
          return CultureInfo.CurrentCulture.CompareInfo.Compare(strA, strB, CompareOptions.IgnoreCase);
        }
        return CultureInfo.CurrentCulture.CompareInfo.Compare(strA, strB, CompareOptions.None);
    }
 
    // Provides a culture-correct string comparison. strA is compared to strB
    // to determine whether it is lexicographically less, equal, or greater, and then a
    // negative integer, 0, or a positive integer is returned; respectively.
    // The case-sensitive option is set by ignoreCase, and the culture is set
    // by culture
    //
    /**////
    public static int Compare(String strA, String strB, bool ignoreCase, CultureInfo culture) ...{
        if (culture==null) ...{
          throw new ArgumentNullException("culture");
        }
 
        if (ignoreCase) ...{
          return culture.CompareInfo.Compare(strA, strB, CompareOptions.IgnoreCase);
        }
        return culture.CompareInfo.Compare(strA, strB, CompareOptions.None);
    }
 
    // Determines whether two string regions match. The substring of strA beginning
    // at indexA of length count is compared with the substring of strB
    // beginning at indexB of the same length.
    //
    /**////
    public static int Compare(String strA, int indexA, String strB, int indexB, int length) ...{
        int lengthA = length;
        int lengthB = length;

        if (strA!=null) ...{
          if (strA.Length - indexA < lengthA) ...{
            lengthA = (strA.Length - indexA);
          }
        }

        if (strB!=null) ...{
          if (strB.Length - indexB < lengthB) ...{
            lengthB = (strB.Length - indexB);
          }
        }
        return CultureInfo.CurrentCulture.CompareInfo.Compare(strA, indexA, lengthA, strB, indexB, lengthB, CompareOptions.None);
    }
 
 
    // Determines whether two string regions match. The substring of strA beginning
    // at indexA of length count is compared with the substring of strB
    // beginning at indexB of the same length. Case sensitivity is determined by the ignoreCase boolean.
    //
    /**////
    public static int Compare(String strA, int indexA, String strB, int indexB, int length, bool ignoreCase) ...{
        int lengthA = length;
        int lengthB = length;

        if (strA!=null) ...{
          if (strA.Length - indexA < lengthA) ...{
            lengthA = (strA.Length - indexA);
          }
        }

        if (strB!=null) ...{
          if (strB.Length - indexB < lengthB) ...{
            lengthB = (strB.Length - indexB);
          }
        }

        if (ignoreCase) ...{
          return CultureInfo.CurrentCulture.CompareInfo.Compare(strA, indexA, lengthA, strB, indexB, lengthB, CompareOptions.IgnoreCase);
        }
        return CultureInfo.CurrentCulture.CompareInfo.Compare(strA, indexA, lengthA, strB, indexB, lengthB, CompareOptions.None);
    }
 
    // Determines whether two string regions match. The substring of strA beginning
    // at indexA of length length is compared with the substring of strB
    // beginning at indexB of the same length. Case sensitivity is determined by the ignoreCase boolean,
    // and the culture is set by culture.
    //
    /**////
    public static int Compare(String strA, int indexA, String strB, int indexB, int length, bool ignoreCase, CultureInfo culture) ...{
        if (culture==null) ...{
          throw new ArgumentNullException("culture");
        }

        int lengthA = length;
        int lengthB = length;

        if (strA!=null) ...{
          if (strA.Length - indexA < lengthA) ...{
            lengthA = (strA.Length - indexA);
          }
        }

        if (strB!=null) ...{
          if (strB.Length - indexB < lengthB) ...{
            lengthB = (strB.Length - indexB);
          }
        }
 
        if (ignoreCase) ...{
          return culture.CompareInfo.Compare(strA,indexA,lengthA, strB, indexB, lengthB,CompareOptions.IgnoreCase);
        } else ...{
          return culture.CompareInfo.Compare(strA,indexA,lengthA, strB, indexB, lengthB,CompareOptions.None);
        }
    }
 
    // Compares this object to another object, returning an integer that
    // indicates the relationship. This method returns a value less than 0 if this is less than value, 0
    // if this is equal to value, or a value greater than 0
    // if this is greater than value. Strings are considered to be
    // greater than all non-String objects. Note that this means sorted
    // arrays would contain nulls, other objects, then Strings in that order.
    //
    /**////
    public int CompareTo(Object value) ...{
        if (value == null) ...{
          return 1;
        }
       
        if (!(value is String)) ...{
          throw new ArgumentException(Environment.GetResourceString("Arg_MustBeString"));
        }

        return String.Compare(this,(String)value);
    }
 
    // Determines the sorting relation of StrB to the current instance.
    //
    /**////
    public int CompareTo(String strB) ...{
        if (strB==null) ...{
          return 1;
        }
        return CultureInfo.CurrentCulture.CompareInfo.Compare(this, strB, 0);
    }
 
    // Compares strA and strB using an ordinal (code-point) comparison.
    //
    /**////
    public static int CompareOrdinal(String strA, String strB) ...{
        if (strA == null || strB == null) ...{
          if ((Object)strA==(Object)strB) ...{ //they're both null;
            return 0;
          }
          return (strA==null)? -1 : 1; //-1 if A is null, 1 if B is null.
        }
       
        return nativeCompareOrdinal(strA, strB, false);
    }
 
    // Compares strA and strB using an ordinal (code-point) comparison.
    //
    /**////
    public static int CompareOrdinal(String strA, int indexA, String strB, int indexB, int length) ...{
        if (strA == null || strB == null) ...{
          if ((Object)strA==(Object)strB) ...{ //they're both null;
            return 0;
          }
 
          return (strA==null)? -1 : 1; //-1 if A is null, 1 if B is null.
        }
 
        return nativeCompareOrdinalEx(strA, indexA, strB, indexB, length);
    }
 
 
    // Determines whether a specified string is a suffix of the the current instance.
    //
    // The case-sensitive and culture-sensitive option is set by options,
    // and the default culture is used.
    //
    /**////
    public bool EndsWith(String value) ...{
        if (null==value) ...{
          throw new ArgumentNullException("value");
        }
        int valueLen = value.Length;
        int thisLen = this.Length;
        if (valueLen>thisLen) ...{
          return false;
        }
        return (0==Compare(this, thisLen-valueLen, value, 0, valueLen));
    }

    internal bool EndsWith(char value) ...{
        int thisLen = this.Length;
        if (thisLen != 0) ...{
          if (this[thisLen - 1] == value)
            return true;
        }
        return false;
    }
 
 
    // Returns the index of the first occurance of value in the current instance.
    // The search starts at startIndex and runs thorough the next count characters.
    //
    /**////
    public int IndexOf(char value) ...{
        return IndexOf(value, 0, this.Length);
    }
 
    /**////
    public int IndexOf(char value, int startIndex) ...{
        return IndexOf(value, startIndex, this.Length - startIndex);
    }
 
    /**////
    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    public extern int IndexOf(char value, int startIndex, int count);
 
    // Returns the index of the first occurance of any character in value in the current instance.
    // The search starts at startIndex and runs to endIndex-1. [startIndex,endIndex).
    //
   
    /**////
    public int IndexOfAny(char [] anyOf) ...{
        return IndexOfAny(anyOf,0, this.Length);
    }
 
    /**////
    public int IndexOfAny(char [] anyOf, int startIndex) ...{
        return IndexOfAny(anyOf, startIndex, this.Length - startIndex);
    }
 
    /**////
    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    public extern int IndexOfAny(char [] anyOf, int startIndex, int count);
 
 
    // Determines the position within this string of the first occurence of the specified
    // string, according to the specified search criteria. The search begins at
    // the first character of this string, it is case-sensitive and culture-sensitive,
    // and the default culture is used.
    //
    /**////
    public int IndexOf(String value) ...{
        return CultureInfo.CurrentCulture.CompareInfo.IndexOf(this,value);
    }
 
    // Determines the position within this string of the first occurence of the specified
    // string, according to the specified search criteria. The search begins at
    // startIndex, it is case-sensitive and culture-sensitve, and the default culture is used.
    //
    /**////
    public int IndexOf(String value, int startIndex)...{
        return CultureInfo.CurrentCulture.CompareInfo.IndexOf(this,value,startIndex);
    }
 
    // Determines the position within this string of the first occurence of the specified
    // string, according to the specified search criteria. The search begins at
    // startIndex, ends at endIndex and the default culture is used.
    //
    /**////
    public int IndexOf(String value, int startIndex, int count)...{
        if (startIndex + count > this.Length) ...{
          throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Index"));
        }
        return CultureInfo.CurrentCulture.CompareInfo.IndexOf(this, value, startIndex, count, CompareOptions.None);
    }
 
 
    // Returns the index of the last occurance of value in the current instance.
    // The search starts at startIndex and runs to endIndex. [startIndex,endIndex].
    // The character at position startIndex is included in the search. startIndex is the larger
    // index within the string.
    //
    /**////
    public int LastIndexOf(char value) ...{
        return LastIndexOf(value, this.Length-1, this.Length);
    }
 
    /**////
    public int LastIndexOf(char value, int startIndex)...{
        return LastIndexOf(value,startIndex,startIndex + 1);
    }
 
    /**////
    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    public extern int LastIndexOf(char value, int startIndex, int count);
 
    // Returns the index of the last occurance of any character in value in the current instance.
    // The search starts at startIndex and runs to endIndex. [startIndex,endIndex].
    // The character at position startIndex is included in the search. startIndex is the larger
    // index within the string.
    //
   
    /**////
    public int LastIndexOfAny(char [] anyOf) ...{
        return LastIndexOfAny(anyOf,this.Length-1,this.Length);
    }
 
    /**////
    public int LastIndexOfAny(char [] anyOf, int startIndex) ...{
        return LastIndexOfAny(anyOf,startIndex,startIndex + 1);
    }
 
    /**////
    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    public extern int LastIndexOfAny(char [] anyOf, int startIndex, int count);
 
 
    // Returns the index of the last occurance of any character in value in the current instance.
    // The search starts at startIndex and runs to endIndex. [startIndex,endIndex].
    // The character at position startIndex is included in the search. startIndex is the larger
    // index within the string.
    //
    /**////
    public int LastIndexOf(String value) ...{
        return LastIndexOf(value, this.Length-1,this.Length);
    }
 
    /**////
    public int LastIndexOf(String value, int startIndex) ...{
        return LastIndexOf(value, startIndex, startIndex + 1);
    }
 
    /**////
    public int LastIndexOf(String value, int startIndex, int count) ...{
        if (count<0) ...{
          throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Count"));
        }
        return CultureInfo.CurrentCulture.CompareInfo.LastIndexOf(this, value, startIndex, count, CompareOptions.None);
    }
 
 
    //
    //
    /**////
    public String PadLeft(int totalWidth) ...{
        return PadHelper(totalWidth, ' ', false);
    }
 
    /**////
    public String PadLeft(int totalWidth, char paddingChar) ...{
        return PadHelper(totalWidth, paddingChar, false);
    }
   
    /**////
    public String PadRight(int totalWidth) ...{
        return PadHelper(totalWidth, ' ', true);
    }
 
    /**////
    public String PadRight(int totalWidth, char paddingChar) ...{
        return PadHelper(totalWidth, paddingChar, true);
    }

你可能感兴趣的:(String)