5 // Patrik Torstensson (patrik.torstensson@labs2.com)
6 // Jeffrey Stedfast (fejj@ximian.com)
7 // Dan Lewis (dihlewis@yahoo.co.uk)
9 // (C) 2001 Ximian, Inc. http://www.ximian.com
14 using System.Collections;
15 using System.Globalization;
16 using System.Runtime.CompilerServices;
19 public sealed class String : IConvertible, IComparable, ICloneable, IEnumerable {
22 public static readonly String Empty = "";
24 [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
25 unsafe public extern String(char *value);
27 [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
28 unsafe public extern String(char *value, int sindex, int length);
30 [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
31 unsafe public extern String(sbyte *value);
33 [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
34 unsafe public extern String(sbyte *value, int sindex, int length);
36 [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
37 unsafe public extern String(sbyte *value, int sindex, int length, Encoding enc);
39 [MethodImplAttribute(MethodImplOptions.InternalCall)]
40 public extern String(char [] val, int sindex, int length);
42 [MethodImplAttribute(MethodImplOptions.InternalCall)]
43 public extern String(char [] val);
45 [MethodImplAttribute(MethodImplOptions.InternalCall)]
46 public extern String(char c, int count);
48 [MethodImplAttribute(MethodImplOptions.InternalCall)]
49 public extern override int GetHashCode();
51 public static bool Equals(String str1, String str2) {
52 if ((Object) str1 == (Object) str2)
55 if (null == (Object) str1 || null == (Object) str2)
58 if (str1.length != str2.length)
61 return InternalEquals(str1, str2);
64 public static bool operator == (String str1, String str2) {
65 return Equals(str1, str2);
68 public static bool operator != (String str1, String str2) {
69 return !Equals(str1, str2);
72 public override bool Equals(Object obj) {
79 return InternalEquals(this, (String) obj);
82 public bool Equals(String value) {
86 if (length != value.length)
89 return InternalEquals(this, value);
92 [IndexerName("Chars")]
93 public extern char this[int index] {
94 [MethodImplAttribute(MethodImplOptions.InternalCall)]
98 public Object Clone() {
102 public TypeCode GetTypeCode () {
103 return TypeCode.String;
106 public void CopyTo(int sindex, char[] dest, int dindex, int count) {
107 // LAMESPEC: should I null-terminate?
110 throw new ArgumentNullException();
112 if (sindex < 0 || dindex < 0 || count < 0)
113 throw new ArgumentOutOfRangeException ();
115 if (sindex + count > Length)
116 throw new ArgumentOutOfRangeException ();
118 if (dindex + count > dest.Length)
119 throw new ArgumentOutOfRangeException ();
121 InternalCopyTo(sindex, dest, dindex, count);
124 public char[] ToCharArray() {
125 return ToCharArray(0, length);
128 public char[] ToCharArray(int sindex, int length) {
129 if (sindex < 0 || length < 0 || sindex + length > this.length)
130 throw new ArgumentOutOfRangeException ();
132 char [] tmp = new char[length];
134 InternalCopyTo(sindex, tmp, 0, length);
139 public String [] Split(params char [] separator) {
140 return Split(separator, Int32.MaxValue);
143 public String[] Split(char[] separator, int count) {
144 if (null == separator) {
145 separator = WhiteChars;
149 throw new ArgumentOutOfRangeException ();
152 return new String[0];
155 return new String[1] { ToString() };
157 return InternalSplit(separator, count);
160 public String Substring (int sindex) {
161 if (sindex < 0 || sindex > this.length) {
162 throw new ArgumentOutOfRangeException();
165 string tmp = InternalAllocateStr(this.length - sindex);
166 InternalStrcpy(tmp, 0, this, sindex, length - sindex);
171 public String Substring (int sindex, int length) {
172 if (length < 0 || sindex < 0 || sindex + length > this.length) {
173 throw new ArgumentOutOfRangeException();
179 string tmp = InternalAllocateStr(length);
180 InternalStrcpy(tmp, 0, this, sindex, length);
185 private static readonly char[] WhiteChars = { (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,
186 (char) 0x2006, (char) 0x2007, (char) 0x2008, (char) 0x2009, (char) 0x200A, (char) 0x200B, (char) 0x3000, (char) 0xFEFF };
188 public String Trim(params char[] chars) {
189 if (null == chars || chars.Length == 0)
192 return InternalTrim(chars, 0);
195 public String TrimStart(params char[] chars) {
196 if (null == chars || chars.Length == 0)
199 return InternalTrim(chars, 1);
202 public String TrimEnd(params char[] chars) {
203 if (null == chars || chars.Length == 0)
206 return InternalTrim(chars, 2);
209 public static int Compare(String s1, String s2) {
210 return Compare(s1, s2, false);
213 public static int Compare(String s1, String s2, bool inCase) {
219 } else if (null == s2)
222 return InternalCompare(s1, 0, s2, 0, Math.Max(s1.length, s2.length), inCase);
226 public static int Compare(String s1, String s2, bool inCase, CultureInfo culture) {
227 return Compare(s1, s2, inCase);
230 public static int Compare(String s1, int i1, String s2, int i2, int length) {
231 return Compare(s1, i1, s2, i2, length, false);
234 public static int Compare(String s1, int i1, String s2, int i2, int length, bool inCase) {
240 } else if (null == s2)
243 if (length < 0 || i1 < 0 || i2 < 0)
244 throw new ArgumentOutOfRangeException ();
246 if (i1 > s1.length || i2 > s2.length)
247 throw new ArgumentOutOfRangeException ();
252 return InternalCompare(s1, i1, s2, i2, length, inCase);
256 public static int Compare(String s1, int i1, String s2, int i2, int length, bool inCase, CultureInfo culture) {
257 return Compare(s1, i1, s2, i2, length, inCase);
260 public int CompareTo(Object value) {
264 if (!(value is String))
265 throw new ArgumentException();
267 return String.Compare(this, (String) value, false);
270 public int CompareTo(String str) {
274 return Compare(this, str, false);
277 public static int CompareOrdinal(String s1, String s2) {
278 if (null == s1 || null == s2) {
279 if ((Object)s1 == (Object) s2) {
283 return (s1 == null) ? -1 : 1;
286 return InternalCompare(s1, 0, s2, 0, Math.Max(s1.length, s2.length), false);
289 public static int CompareOrdinal(String s1, int i1, String s2, int i2, int length) {
290 if (null == s1 || null == s2) {
291 if ((Object)s1 == (Object) s2) {
295 return (s1 == null) ? -1 : 1;
298 if (i1 < 0 || i2 < 0 || length < 0)
299 throw new ArgumentOutOfRangeException ();
301 if (i1 > s1.length || i2 > s2.length)
302 throw new ArgumentOutOfRangeException ();
304 return InternalCompare(s1, i1, s2, i2, length, false);
307 public bool EndsWith(String value) {
309 throw new ArgumentNullException();
311 if (value.length > this.length) {
315 return (0 == Compare(this, length - value.length, value, 0, value.length));
318 public int IndexOfAny(char [] arr) {
320 throw new ArgumentNullException();
322 return InternalIndexOfAny(arr, 0, this.length);
325 public int IndexOfAny(char [] arr, int sindex) {
327 throw new ArgumentNullException();
328 if (sindex < 0 || sindex >= this.length)
329 throw new ArgumentOutOfRangeException();
331 return InternalIndexOfAny(arr, sindex, this.length - sindex);
334 public int IndexOfAny(char [] arr, int sindex, int count) {
336 throw new ArgumentNullException();
337 if (sindex < 0 || count < 0 || sindex + count > this.length)
338 throw new ArgumentOutOfRangeException ();
340 return InternalIndexOfAny(arr, sindex, count);
343 public int IndexOf(char value) {
344 return InternalIndexOf(value, 0, this.length);
347 public int IndexOf(String value) {
348 return IndexOf(value, 0, this.length);
351 public int IndexOf(char value, int sindex) {
352 if (sindex < 0 || sindex >= this.length) {
353 throw new ArgumentOutOfRangeException();
356 return InternalIndexOf(value, sindex, this.length - sindex);
359 public int IndexOf(String value, int sindex) {
360 return IndexOf(value, sindex, this.length - sindex);
363 public int IndexOf(char value, int sindex, int count) {
364 if (sindex < 0 || count < 0 || sindex + count > this.length)
365 throw new ArgumentOutOfRangeException ();
367 if (sindex == 0 && this.length == 0)
370 return InternalIndexOf(value, sindex, count);
373 public int IndexOf(String value, int sindex, int count) {
375 throw new ArgumentNullException();
377 if (sindex < 0 || count < 0 || sindex + count > this.length)
378 throw new ArgumentOutOfRangeException ();
380 if (sindex == 0 && this.length == 0)
383 return InternalIndexOf(value, sindex, count);
386 public int LastIndexOfAny(char [] arr) {
388 throw new ArgumentNullException();
390 return InternalLastIndexOfAny(arr, this.length - 1, this.length);
393 public int LastIndexOfAny(char [] arr, int sindex) {
395 throw new ArgumentNullException();
397 if (sindex < 0 || sindex > this.length)
398 throw new ArgumentOutOfRangeException();
400 if (this.length == 0)
403 return InternalLastIndexOfAny(arr, sindex, sindex + 1);
406 public int LastIndexOfAny(char [] arr, int sindex, int count) {
408 throw new ArgumentNullException();
410 if (sindex < 0 || count < 0 || sindex > this.length || sindex - count < -1)
411 throw new ArgumentOutOfRangeException();
413 if (this.length == 0)
416 return InternalLastIndexOfAny(arr, sindex, count);
419 public int LastIndexOf(char value) {
420 return InternalLastIndexOf(value, this.length - 1, this.length);
423 public int LastIndexOf(String value) {
425 throw new ArgumentNullException();
427 if (value.length == 0)
430 if (this.length == 0)
433 return InternalLastIndexOf(value, this.length - 1, this.length);
436 public int LastIndexOf(char value, int sindex){
437 return LastIndexOf(value, sindex, sindex + 1);
440 public int LastIndexOf(String value, int sindex) {
441 return LastIndexOf(value, sindex, sindex + 1);
444 public int LastIndexOf(char value, int sindex, int count) {
445 if (sindex < 0 || count < 0)
446 throw new ArgumentOutOfRangeException ();
448 if (sindex >= this.length || sindex - count + 1 < 0)
449 throw new ArgumentOutOfRangeException ();
451 if (sindex == 0 && this.length == 0)
454 return InternalLastIndexOf(value, sindex, count);
457 public int LastIndexOf(String value, int sindex, int count) {
459 throw new ArgumentNullException();
461 if (sindex < 0 || sindex > this.length)
462 throw new ArgumentOutOfRangeException ();
464 if (count < 0 || sindex - count + 1 < 0)
465 throw new ArgumentOutOfRangeException ();
467 if (value.length > sindex)
470 if (value == String.Empty)
473 if (sindex == 0 && this.length == 0)
476 return InternalLastIndexOf(value, sindex, count);
479 public String PadLeft(int width) {
480 return PadLeft(width, ' ');
483 public String PadLeft(int width, char chr) {
485 throw new ArgumentException();
487 if (width < this.length)
488 return String.Copy(this);
490 return InternalPad(width, chr, false);
493 public String PadRight(int width) {
494 return PadRight(width, ' ');
497 public String PadRight(int width, char chr) {
499 throw new ArgumentException();
501 if (width < this.length)
502 return String.Copy(this);
504 return InternalPad(width, chr, true);
507 public bool StartsWith(String value) {
509 throw new ArgumentNullException();
511 if (this.length < value.length)
514 return (0 == Compare(this, 0, value, 0 , value.length));
518 public String Replace (char oldChar, char newChar) {
519 return InternalReplace(oldChar, newChar);
522 public String Replace(String oldValue, String newValue) {
523 if (null == oldValue)
524 throw new ArgumentNullException();
526 return InternalReplace(oldValue, newValue);
529 public String Remove(int sindex, int count) {
530 if (sindex < 0 || count < 0 || sindex + count > this.length)
531 throw new ArgumentOutOfRangeException ();
533 return InternalRemove(sindex, count);
536 public String ToLower() {
537 return InternalToLower();
540 public String ToLower(CultureInfo culture) {
541 throw new NotImplementedException();
544 public String ToUpper() {
545 return InternalToUpper();
548 public String ToUpper(CultureInfo culture) {
549 throw new NotImplementedException();
552 public override String ToString() {
556 public String ToString(IFormatProvider provider) {
560 public String Trim() {
564 public static String Format(String format, Object arg0) {
565 return Format(null, format, new Object[] {arg0});
568 public static String Format(String format, Object arg0, Object arg1) {
569 return Format(null, format, new Object[] {arg0, arg1});
572 public static String Format(String format, Object arg0, Object arg1, Object arg2) {
573 return Format(null, format, new Object[] {arg0, arg1, arg2});
576 public static string Format (string format, params object[] args) {
577 return Format (null, format, args);
580 public static string Format (IFormatProvider provider, string format, params object[] args) {
581 if (format == null || args == null)
582 throw new ArgumentNullException ();
584 StringBuilder result = new StringBuilder ();
588 while (ptr < format.length) {
589 char c = format[ptr ++];
592 result.Append (format, start, ptr - start - 1);
594 // check for escaped open bracket
596 if (format[ptr] == '{') {
607 ParseFormatSpecifier (format, ref ptr, out n, out width, out left_align, out arg_format);
608 if (n >= args.Length)
609 throw new FormatException ("Index (zero based) must be greater than or equal to zero and less than the size of the argument list.");
613 object arg = args[n];
618 else if (arg is IFormattable)
619 str = ((IFormattable)arg).ToString (arg_format, provider);
621 str = arg.ToString ();
623 // pad formatted string and append to result
625 if (width > str.length) {
626 string pad = new String (' ', width - str.length);
642 else if (c == '}' && format[ptr] == '}') {
643 result.Append (format, start, ptr - start - 1);
648 if (start < format.length)
649 result.Append (format.Substring (start));
651 return result.ToString ();
654 public static String Copy (String str) {
656 throw new ArgumentNullException ();
658 int length = str.length;
660 String tmp = InternalAllocateStr(length);
661 InternalStrcpy(tmp, 0, str);
665 public static String Concat(Object obj) {
669 return obj.ToString();
672 public static String Concat(Object obj1, Object obj2) {
679 return Concat(obj1.ToString(), obj2.ToString());
682 public static String Concat(Object obj1, Object obj2, Object obj3) {
692 return Concat(obj1.ToString(), obj2.ToString(), obj3.ToString());
696 // I can not find the "__arglist" argument on the spec
699 [CLSCompliant(false)]
700 public static String Concat (Object arg0, Object arg1, Object arg2, Object arg3, __arglist) {
701 throw new NotImplementedException();
705 public static String Concat(String s1, String s2) {
707 if (null == s2) { return String.Empty; }
711 if (null == s2) { return s1; }
713 String tmp = InternalAllocateStr(s1.length + s2.length);
715 InternalStrcpy(tmp, 0, s1);
716 InternalStrcpy(tmp, s1.length, s2);
721 public static String Concat(String s1, String s2, String s3) {
722 if (null == s1 && null == s2 && null == s3) {
726 if (null == s1) { s1 = String.Empty; }
727 if (null == s2) { s2 = String.Empty; }
728 if (null == s3) { s3 = String.Empty; }
730 String tmp = InternalAllocateStr(s1.length + s2.length + s3.length);
732 InternalStrcpy(tmp, 0, s1);
733 InternalStrcpy(tmp, s1.length, s2);
734 InternalStrcpy(tmp, s1.length + s2.length, s3);
739 public static String Concat(String s1, String s2, String s3, String s4) {
740 if (null == s1 && null == s2 && null == s3 && null == s4) {
744 if (null == s1) { s1 = String.Empty; }
745 if (null == s2) { s2 = String.Empty; }
746 if (null == s3) { s3 = String.Empty; }
747 if (null == s4) { s4 = String.Empty; }
749 String tmp = InternalAllocateStr(s1.length + s2.length + s3.length + s4.length);
751 InternalStrcpy(tmp, 0, s1);
752 InternalStrcpy(tmp, s1.length, s2);
753 InternalStrcpy(tmp, s1.length + s2.length, s3);
754 InternalStrcpy(tmp, s1.length + s2.length + s3.length, s4);
759 public static String Concat(params Object[] args) {
761 int len, i, currentpos;
764 throw new ArgumentNullException ();
766 strings = new string [args.Length];
769 foreach (object arg in args) {
770 /* use Empty for each null argument */
772 strings[i] = String.Empty;
774 strings[i] = arg.ToString ();
775 len += strings[i].length;
784 String tmp = InternalAllocateStr(len);
785 for (i = 0; i < strings.Length; i++) {
786 InternalStrcpy(tmp, currentpos, strings[i]);
787 currentpos += strings[i].length;
793 public static String Concat(params String[] values) {
794 int len, i, currentpos;
797 throw new ArgumentNullException ();
800 foreach (string value in values)
801 len += value != null ? value.length : 0;
808 String tmp = InternalAllocateStr(len);
809 for (i = 0; i < values.Length; i++) {
810 if (values[i] == null)
813 InternalStrcpy(tmp, currentpos, values[i]);
814 currentpos += values[i].length;
820 public String Insert(int sindex, String value) {
822 throw new ArgumentNullException();
824 if (sindex < 0 || sindex > this.length)
825 throw new ArgumentOutOfRangeException();
827 return InternalInsert(sindex, value);
831 public static string Intern (string str) {
833 throw new ArgumentNullException ();
835 return InternalIntern(str);
838 public static string IsInterned (string str) {
840 throw new ArgumentNullException();
842 return InternalIsInterned(str);
845 public static string Join (string separator, string [] value) {
847 throw new ArgumentNullException ();
849 return Join(separator, value, 0, value.Length);
852 public static string Join(string separator, string[] value, int sindex, int count) {
854 throw new ArgumentNullException ();
856 if (sindex + count > value.Length)
857 throw new ArgumentOutOfRangeException ();
859 if (sindex == value.Length)
862 return InternalJoin(separator, value, sindex, count);
865 bool IConvertible.ToBoolean (IFormatProvider provider) {
866 return Convert.ToBoolean (this);
869 byte IConvertible.ToByte (IFormatProvider provider) {
870 return Convert.ToByte (this);
873 char IConvertible.ToChar (IFormatProvider provider) {
874 return Convert.ToChar (this);
877 DateTime IConvertible.ToDateTime (IFormatProvider provider) {
878 return Convert.ToDateTime (this);
881 decimal IConvertible.ToDecimal (IFormatProvider provider) {
882 return Convert.ToDecimal (this);
885 double IConvertible.ToDouble (IFormatProvider provider) {
886 return Convert.ToDouble (this);
889 short IConvertible.ToInt16 (IFormatProvider provider) {
890 return Convert.ToInt16 (this);
893 int IConvertible.ToInt32 (IFormatProvider provider) {
894 return Convert.ToInt32 (this);
897 long IConvertible.ToInt64 (IFormatProvider provider) {
898 return Convert.ToInt64 (this);
901 [CLSCompliant(false)]
902 sbyte IConvertible.ToSByte (IFormatProvider provider) {
903 return Convert.ToSByte (this);
906 float IConvertible.ToSingle (IFormatProvider provider) {
907 return Convert.ToSingle (this);
909 string IConvertible.ToString (IFormatProvider format) {
913 object IConvertible.ToType (Type conversionType, IFormatProvider provider) {
914 return Convert.ToType (this, conversionType, provider);
917 [CLSCompliant(false)]
918 ushort IConvertible.ToUInt16 (IFormatProvider provider) {
919 return Convert.ToUInt16 (this);
922 [CLSCompliant(false)]
923 uint IConvertible.ToUInt32 (IFormatProvider provider) {
924 return Convert.ToUInt32 (this);
927 [CLSCompliant(false)]
928 ulong IConvertible.ToUInt64 (IFormatProvider provider) {
929 return Convert.ToUInt64 (this);
932 TypeCode IConvertible.GetTypeCode () {
933 return TypeCode.String;
942 public CharEnumerator GetEnumerator () {
943 return new CharEnumerator (this);
946 IEnumerator IEnumerable.GetEnumerator () {
947 return new CharEnumerator (this);
950 private static void ParseFormatSpecifier (string str, ref int ptr, out int n, out int width, out bool left_align, out string format) {
951 // parses format specifier of form:
957 // N = argument number (non-negative integer)
959 n = ParseDecimal (str, ref ptr);
961 throw new FormatException ("Input string was not in correct format.");
963 // M = width (non-negative integer)
965 if (str[ptr] == ',') {
966 left_align = (str[++ ptr] == '-');
970 width = ParseDecimal (str, ref ptr);
972 throw new FormatException ("Input string was not in correct format.");
979 // F = argument format (string)
981 if (str[ptr] == ':') {
983 while (str[ptr] != '}')
986 format = str.Substring (start, ptr - start);
991 if (str[ptr ++] != '}')
992 throw new FormatException ("Input string was not in correct format.");
994 catch (IndexOutOfRangeException) {
995 throw new FormatException ("Input string was not in correct format.");
999 private static int ParseDecimal (string str, ref int ptr) {
1004 if (c < '0' || '9' < c)
1007 n = n * 10 + c - '0';
1018 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1019 private extern static string InternalJoin(string separator, string[] value, int sindex, int count);
1021 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1022 private extern String InternalInsert(int sindex, String value);
1024 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1025 private extern String InternalReplace(char oldChar, char newChar);
1027 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1028 private extern String InternalReplace(String oldValue, String newValue);
1030 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1031 private extern String InternalRemove(int sindex, int count);
1033 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1034 private extern void InternalCopyTo(int sindex, char[] dest, int dindex, int count);
1036 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1037 private extern String[] InternalSplit(char[] separator, int count);
1039 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1040 private extern String InternalTrim(char[] chars, int typ);
1042 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1043 private extern int InternalIndexOf(char value, int sindex, int count);
1045 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1046 private extern int InternalIndexOf(string value, int sindex, int count);
1048 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1049 private extern int InternalIndexOfAny(char [] arr, int sindex, int count);
1051 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1052 private extern int InternalLastIndexOf(char value, int sindex, int count);
1054 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1055 private extern int InternalLastIndexOf(String value, int sindex, int count);
1057 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1058 private extern int InternalLastIndexOfAny(char [] anyOf, int sindex, int count);
1060 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1061 private extern String InternalPad(int width, char chr, bool right);
1063 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1064 private extern String InternalToLower();
1066 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1067 private extern String InternalToUpper();
1069 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1070 private extern static String InternalAllocateStr(int length);
1072 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1073 private extern static void InternalStrcpy(String dest, int destPos, String src);
1075 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1076 private extern static void InternalStrcpy(String dest, int destPos, String src, int startPos, int count);
1078 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1079 private extern static string InternalIntern(string str);
1081 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1082 private extern static string InternalIsInterned(string str);
1084 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1085 private extern static int InternalCompare(String s1, int i1, String s2, int i2, int length, bool inCase);
1087 [MethodImplAttribute(MethodImplOptions.InternalCall)]
1088 private extern static bool InternalEquals(String s1, String s2);