Должно ли StringBuilder.Capacity
быть установлено на максимальное количество символов .NET, независимо от нулевого завершения, или оно должно быть установлено на один уровень выше, чтобы резервировать пространство для нулевого терминатора при использовании P / Invoke.
Естественная реакция заключается в том, что он должен быть установлен на один уровень выше, но похоже, что P / Invoke должен автоматически компенсировать это. На самом деле это действительно задокументировано прямо здесь: http://msdn.microsoft.com/en-US/library/s9ts558h(v=VS.100).aspx
Причина этого вопроса в том, что большинство примеров не полностью соответствуют вышеуказанной документации. Почти всегда они кодируются:
StringBuilder sb = new StringBuilder(dotNetChars + 1);
SomeWindowsAPI(sb, sb.Capacity);
Вместо:
StringBuilder sb = new StringBuilder(dotNetChars);
SomeWindowsAPI(sb, sb.Capacity + 1);
(Я понимаю, что некоторые API по-разному обрабатывают параметр размера буфера. Предположим, что API обрабатывает это, что является обязательным, как GetFullPathName
: http://msdn.microsoft.com/en-us/library/aa364963(v=VS.85).aspx)
Использование выражения с sb.Capacity
непосредственно в вызове API представляется наилучшей практикой во избежание несоответствия. Вопрос в том, правильно ли добавить +1.
Оглянись вокруг. Вы, вероятно, обнаружите, что единственное место, где отображается sb.Capacity + 1
, - это документация MSDN.
Конечно, на стороне предосторожности можно выделить больший буфер, чем это строго необходимо, но я хотел бы узнать консенсус о том, как это сделать.