Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unsafe code to change length (by mutation!) of a String object?

As .NET doesn't use C style nulls to end a string how can I keep the allocated string but change the length of it by using unsafe code?

As I understand .NET using a 20 bytes header for every string, presumably this is where the length of the string is stored, is there anyway to directly modify this length? So .NET will keep the string in memory but when I call .Length it'll return the .Length I want.

if this is possible, also it would be interesting to hear all crazy possible side-effects of this

UPDATE

I'm trying accomplish this without using reflection.

like image 243
dr. evil Avatar asked Nov 18 '11 01:11

dr. evil


People also ask

What is unsafe code c#?

Unsafe code in C# isn't necessarily dangerous; it's just code whose safety cannot be verified. Unsafe code has the following properties: Methods, types, and code blocks can be defined as unsafe. In some cases, unsafe code may increase an application's performance by removing array bounds checks.

Can we modify string in c#?

You can produce a character array from a string, modify the contents of the array, and then create a new string from the modified contents of the array. The following example shows how to replace a set of characters in a string. First, it uses the String. ToCharArray() method to create an array of characters.

Why do we use 0 in C#?

The “0” custom specifier is a zero placeholder. If the value to be formatted has a digit in the position where the zero appears in the format string, the the digit is copied to the resultant string. However, if this doesn't happen, then a zero appears.

How do you change a character in a string in C#?

Strings in c# are immutable objects - it's not possible to replace or remove a char directly. The solution is to create a new string with the given char replaced or removed.


1 Answers

From Strings UNDOCUMENTED

public static unsafe void SetLength(string s, int length)
{
    fixed(char *p = s)
    {
        int *pi = (int *)p;
        if (length<0 || length > pi[-2])
            throw( new ArgumentOutOfRangeException("length") );
        pi[-1] = length;
        p[length] = '\0';
    }
}
like image 73
Chris Fulstow Avatar answered Oct 19 '22 11:10

Chris Fulstow