Since strings in C# are variable-based, they starts with 32-bit integer that tells how many characters stored in string. So the answer will be 2^32 if we ignore the limitation of the system.
If we imagine that we have completely filled the memory, it's representation in memory will have: 8 (SyncBlock) + 8 (Virtual Table Pointer) + 4 (m_arrayLength before .NET Framework 4.0, or padding for later versions) + 2 * length (characters itself) + 2 (null-terminator) = (26 + 2 * length) bytes in 64-bit system.
In reality, you'll never fill out the string completely, because you'll hit the 2Gb limits faster :)
I recommend to read this article for deeper knowledge about string implementation (use translator): https://habr.com/ru/articles/727300/