Index: Encoding.cs
===================================================================
--- Encoding.cs	(revision 59399)
+++ Encoding.cs	(working copy)
@@ -663,7 +663,10 @@
 	}
 	public virtual String GetString (byte[] bytes)
 	{
-		return new String (GetChars(bytes));
+		if (bytes == null)
+			throw new ArgumentNullException ("bytes");
+
+		return GetString (bytes, 0, bytes.Length);
 	}
 
 #if !ECMA_COMPAT
Index: UnicodeEncoding.cs
===================================================================
--- UnicodeEncoding.cs	(revision 59399)
+++ UnicodeEncoding.cs	(working copy)
@@ -146,8 +146,7 @@
 				return GetBytesInternal (charPtr + charIndex, charCount, bytePtr + byteIndex, byteCount);
 	}
 
-#if !NET_2_0
-	public unsafe override byte [] GetBytes (String s)
+	public override byte [] GetBytes (String s)
 	{
 		if (s == null)
 			throw new ArgumentNullException ("s");
@@ -155,14 +154,10 @@
 		int byteCount = GetByteCount (s);
 		byte [] bytes = new byte [byteCount];
 
-		if (byteCount != 0)
-			fixed (char* charPtr = s)
-				fixed (byte* bytePtr = bytes)
-					GetBytesInternal (charPtr, s.Length, bytePtr, byteCount);
+		GetBytes (s, 0, s.Length, bytes, 0);
 
 		return bytes;
 	}
-#endif
 
 	public unsafe override int GetBytes (String s, int charIndex, int charCount,
 										byte [] bytes, int byteIndex)
@@ -183,6 +178,10 @@
 			throw new ArgumentOutOfRangeException ("byteIndex", _("ArgRange_Array"));
 		}
 
+		// For consistency
+		if (charCount == 0)
+			return 0;
+
 		int byteCount = bytes.Length - byteIndex;
 		if (bytes.Length == 0)
 			bytes = new byte [1];
@@ -300,6 +299,30 @@
 	}
 #endif
 
+	// Decode a buffer of bytes into a string.
+	public unsafe override String GetString (byte [] bytes, int index, int count)
+	{
+		if (bytes == null)
+			throw new ArgumentNullException ("bytes");
+		if (index < 0 || index > bytes.Length)
+			throw new ArgumentOutOfRangeException ("index", _("ArgRange_Array"));
+		if (count < 0 || count > (bytes.Length - index))
+			throw new ArgumentOutOfRangeException ("count", _("ArgRange_Array"));
+
+		if (count == 0)
+			return string.Empty;
+
+		// GetCharCountInternal
+		int charCount = count / 2;
+		string s = string.InternalAllocateStr (charCount);
+
+		fixed (byte* bytePtr = bytes)
+			fixed (char* charPtr = s)
+				GetCharsInternal (bytePtr + index, count, charPtr, charCount);
+
+		return s;
+	}
+
 	private unsafe int GetCharsInternal (byte* bytes, int byteCount,
 										char* chars, int charCount)
 	{
