You
have obtained a pointer to a
byte
array, an sbyte
array, or
a char
array. You want to convert this array into
its string
equivalent.
Use one of the string
object’s
constructors that build a string from either a
byte*
, sbyte*
, or
char*
passed in as a parameter. The following
overloaded ConvertToString
methods accept a
byte[]
, an sbyte[]
, or a
char[]
and return the equivalent
string
object created from these
arrays:
public string ConvertToString(byte[] arr) { unsafe { string returnStr; fixed(byte* fixedPtr = arr) { returnStr = new string((sbyte*)fixedPtr); } } return (returnStr); } public string ConvertToString(sbyte[] arr) { unsafe { string returnStr; fixed(sbyte* fixedPtr = arr) { returnStr = new string(fixedPtr); } } return (returnStr); } public string ConvertToString(char[] arr) { unsafe { string returnStr; fixed(char* fixedPtr = arr) { returnStr = new string(fixedPtr); } } return (returnStr); }
The following code calls these methods, passing in one of the required array types:
Console.WriteLine(ConvertToString(new byte[3] {0x61,0x62,0x63})); Console.WriteLine(ConvertToString(new char[3] {'a','b','c'})); Console.WriteLine(ConvertToString(new sbyte[3] {0x61,0x62,0x63}));
The System.String
constructor that takes an
sbyte*
in the Solution code is expecting a
null
-terminated string in the buffer. There are
also constructors on System.String
that take an
sbyte*
and default to Unicode, or allow you to
pass an Encoding
object. One method to create a
string from these arrays is to use a foreach
loop
to iterate over each element in the array and append the character
value of each array element to the end of a
StringBuilder
object. However, this would operate
slower than using the technique in this recipe. In fact, assuming a
null
-terminated string is in the byte array, the
following unsafe code to convert a byte
array to a
string
executes in 46%
of the
time of its equivalent safe code:
public string ConvertToString(byte[] arr) { unsafe { string returnStr; fixed(byte* fixedPtr = arr) { returnStr = new string((sbyte*)fixedPtr); } } return (returnStr); }
public string ConvertToStringSlow(byte[] arr) { System.Text.StringBuilder returnStr = new System.Text.StringBuilder( ); foreach (sbyte C in arr) { returnStr.Append(C); } return (returnStr.ToString( )); }
In addition, the unsafe code is twice as fast as the following code,
which uses the Encoding.ASCII
class to convert a
byte
array to a
string
:
public string ConvertToASCIIStringSlow(byte[] arr) { String retStr = Encoding.ASCII.GetString(arr); return (retStr); }
This recipe uses two overloaded string
constructors that accept either a pointer to a
byte
array or a pointer to a
char
array. The constructor then uses this array
to construct a string from the array. The newly created
string
object is then initialized to this string
created from the array. The constructors used in this recipe are
defined as follows:
unsafe public String(char*value
) unsafe public String(sbyte*value
)
The parameter for this constructor is defined as follows:
value
A pointer to either a char
array or an
sbyte
array.
Note that if a pointer to a byte
array is passed
in, it must be cast to an sbyte
:
returnStr = new string((sbyte*)fixedPtr);
Notice that the array’s length is not passed in to
the string
constructor. Instead, the constructor
will keep appending array values to the string until a
null
character is reached. If you know how many
characters are in the array, then you should use the string overload
that allows you to pass in the length.