
рд╕реНрдкреИрди <рдЯреА> рдЙрдкрдпреЛрдЧ рдХреЗ рдЙрджрд╛рд╣рд░рдг
рд╕реНрд╡рднрд╛рд╡ рд╕реЗ рдПрдХ рдорд╛рдирд╡ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕рд╛рдзрди рдХреЗ рдЙрджреНрджреЗрд╢реНрдп рдХреЛ рдирд╣реАрдВ рд╕рдордЭ рд╕рдХрддрд╛ рд╣реИ рдЬрдм рддрдХ рдХрд┐ рдЙрд╕реЗ рдХреБрдЫ рдЕрдиреБрднрд╡ рдкреНрд░рд╛рдкреНрдд рди рд╣реЛред рддреЛ, рдЖрдЗрдП рдХреБрдЫ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреА рдУрд░ рдореБрдбрд╝реЗрдВред
ValueStringBuilder
рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ ValueStringBuilder
рдкреНрд░рдХрд╛рд░ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ mscorlib рдХреЗ рдЕрдВрджрд░ рдЧрд╣рд░реЗ рджрдлрди рд╣реИ рдФрд░ internal
рд╕рдВрд╢реЛрдзрдХ рдХреЗ рд╕рд╛рде рдХрдИ рдЕрдиреНрдп рдмрд╣реБрдд рд╣реА рджрд┐рд▓рдЪрд╕реНрдк рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рд╣реИред рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдЕрдЧрд░ рд╣рдо mscorlib рд╕реНрд░реЛрдд рдХреЛрдб рдкрд░ рд╢реЛрдз рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рд╣рдореЗрдВ рдЕрдиреБрдХреВрд▓рди рдХреЗ рд▓рд┐рдП рдпрд╣ рдЙрд▓реНрд▓реЗрдЦрдиреАрдп рд╕рд╛рдзрди рдирд╣реАрдВ рдорд┐рд▓реЗрдЧрд╛ред
StringBuilder
рд╕рд┐рд╕реНрдЯрдо рдкреНрд░рдХрд╛рд░ рдХрд╛ рдореБрдЦреНрдп рдиреБрдХрд╕рд╛рди рдХреНрдпрд╛ рд╣реИ? рдЗрд╕рдХрд╛ рдореБрдЦреНрдп рджреЛрд╖ рдкреНрд░рдХрд╛рд░ рдФрд░ рдЗрд╕рдХрд╛ рдЖрдзрд╛рд░ рд╣реИ - рдпрд╣ рдПрдХ рд╕рдВрджрд░реНрдн рдкреНрд░рдХрд╛рд░ рд╣реИ рдФрд░ рдпрд╣ char[]
, рдЕрд░реНрдерд╛рддреН рдПрдХ рдЪрд░рд┐рддреНрд░ рд╕рд░рдгреА рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИред рдХрдо рд╕реЗ рдХрдо, рдЗрд╕рдХрд╛ рдорддрд▓рдм рджреЛ рдЪреАрдЬреЗрдВ рд╣реИрдВ: рд╣рдо рд╡реИрд╕реЗ рднреА рдвреЗрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЬреНрдпрд╛рджрд╛ рдирд╣реАрдВ) рдФрд░ рд╕реАрдкреАрдпреВ рдирдХрджреА рдХреЛ рдпрд╛рдж рдХрд░рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдмрдврд╝ рдЬрд╛рддреА рд╣реИред
StringBuilder
рд╕рд╛рде рдПрдХ рдФрд░ рдореБрджреНрджрд╛ рдЬреЛ рдореИрдВрдиреЗ рд╕рд╛рдордирд╛ рдХрд┐рдпрд╛ рд╣реИ рд╡рд╣ рдЫреЛрдЯреЗ рддрд╛рд░реЛрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рд╣реИ, рдЬрдм рдХрд┐ рдкрд░рд┐рдгрд╛рдореА рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХрдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдЬреИрд╕реЗ рдХрд┐ 100 рд╡рд░реНрдгреЛрдВ рд╕реЗ рдХрдоред рд▓рдШреБ рдкреНрд░рд╛рд░реВрдкрдг рдкреНрд░рджрд░реНрд╢рди рдкрд░ рдореБрджреНрджреЛрдВ рдХреЛ рдЙрдард╛рддрд╛ рд╣реИред
рдпрд╣ рдЕрдзреНрдпрд╛рдп рд░реВрд╕реА рд╕реЗ рд╕рдВрдпреБрдХреНрдд рд░реВрдк рд╕реЗ рд▓реЗрдЦрдХ рджреНрд╡рд╛рд░рд╛ рдФрд░ рдкреЗрд╢реЗрд╡рд░ рдЕрдиреБрд╡рд╛рджрдХреЛрдВ рджреНрд╡рд╛рд░рд╛ рдЕрдиреБрд╡рд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ ред рдЖрдк рд░реВрд╕реА рдпрд╛ рдЕрдВрдЧреНрд░реЗрдЬреА рд╕реЗ рдХрд┐рд╕реА рдЕрдиреНрдп рднрд╛рд╖рд╛ рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХрд░рдиреЗ рдореЗрдВ рд╣рдорд╛рд░реА рдорджрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдореБрдЦреНрдпрддрдГ рдЪреАрдиреА рдпрд╛ рдЬрд░реНрдорди рдореЗрдВред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрджрд┐ рдЖрдк рд╣рдореЗрдВ рдзрдиреНрдпрд╡рд╛рдж рджреЗрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рдпрд╣ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдореЗрдВ рдЧрд┐рддреБрдм рдкрд░ рдПрдХ рд╕реНрдЯрд╛рд░ рджреЗрдирд╛ рд╣реИ рдпрд╛ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЛ рдлреЛрд░реНрдХ рдХрд░рдирд╛ рд╣реИ
github / sidristij / dotnetbook ред
$"{x} is in range [{min};{max}]"
рдпрд╣ рдХрд┐рд╕ рд╣рдж рддрдХ StringBuilder
рдорд╛рдзреНрдпрдо рд╕реЗ рдореИрдиреБрдЕрд▓ рдирд┐рд░реНрдорд╛рдг рд╕реЗ рднреА рдмрджрддрд░ рд╣реИ? рдЙрддреНрддрд░ рд╣рдореЗрд╢рд╛ рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рдпрд╣ рдирд┐рд░реНрдорд╛рдг рдХреА рдЬрдЧрд╣ рдФрд░ рдЗрд╕ рдкрджреНрдзрддрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡реГрддреНрддрд┐ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред рдкреНрд░рд╛рд░рдВрдн рдореЗрдВ, string.Format
рдЖрдВрддрд░рд┐рдХ StringBuilder
рд▓рд┐рдП рд╕реНрдореГрддрд┐ рдЖрд╡рдВрдЯрд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬреЛ рд╡рд░реНрдгреЛрдВ рдХреА рдПрдХ рд╕рд░рдгреА рдмрдирд╛рдПрдЧрд╛ (SourceString.Length + args.Length * 8)ред рдпрджрд┐ рд╕рд░рдгреА рдирд┐рд░реНрдорд╛рдг рдХреЗ рджреМрд░рд╛рди рдпрд╣ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рд▓рдВрдмрд╛рдИ рдЧрд▓рдд рддрд░реАрдХреЗ рд╕реЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХреА рдЧрдИ рдереА, рддреЛ рдмрд╛рдХреА рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдФрд░ StringBuilder
рдмрдирд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕рд╕реЗ рдПрдХрд▓ рд▓рд┐рдВрдХреНрдб рд╕реВрдЪреА рдХрд╛ рдирд┐рд░реНрдорд╛рдг рд╣реЛрдЧрд╛ред рдирддреАрдЬрддрди, рдЗрд╕реЗ рдирд┐рд░реНрдорд┐рдд рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдПрдХ рдФрд░ рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ред рд╡рд╣ рдмреЗрдХрд╛рд░ рд╣реИред рдпрд╣ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рд╣рдо рдвреЗрд░ рдкрд░ рдПрдХ рдЧрдард┐рдд рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд╕рд░рдгреА рдХреЛ рдЖрд╡рдВрдЯрд┐рдд рдХрд░рдиреЗ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ: рдпрд╣ рд╣рдорд╛рд░реА рд╕рдорд╕реНрдпрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЛ рд╣рд▓ рдХрд░реЗрдЧрд╛ред
рдЖрдЗрдП рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЛ mscorlib
рдХреА рдЧрд╣рд░рд╛рдИ рд╕реЗ рджреЗрдЦреЗрдВ:
ValueStringBuilder рд╡рд░реНрдЧ
/ src / mscorlib / рд╕рд╛рдЭрд╛ / рдкреНрд░рдгрд╛рд▓реА / рдкрд╛рда / ValueStringBuilder
internal ref struct ValueStringBuilder { // this field will be active if we have too many characters private char[] _arrayToReturnToPool; // this field will be the main private Span<char> _chars; private int _pos; // the type accepts the buffer from the outside, delegating the choice of its size to a calling party public ValueStringBuilder(Span<char> initialBuffer) { _arrayToReturnToPool = null; _chars = initialBuffer; _pos = 0; } public int Length { get => _pos; set { int delta = value - _pos; if (delta > 0) { Append('\0', delta); } else { _pos = value; } } } // Here we get the string by copying characters from the array into another array public override string ToString() { var s = new string(_chars.Slice(0, _pos)); Clear(); return s; } // To insert a required character into the middle of the string //you should add space into the characters of that string and then copy that character public void Insert(int index, char value, int count) { if (_pos > _chars.Length - count) { Grow(count); } int remaining = _pos - index; _chars.Slice(index, remaining).CopyTo(_chars.Slice(index + count)); _chars.Slice(index, count).Fill(value); _pos += count; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(char c) { int pos = _pos; if (pos < _chars.Length) { _chars[pos] = c; _pos = pos + 1; } else { GrowAndAppend(c); } } [MethodImpl(MethodImplOptions.NoInlining)] private void GrowAndAppend(char c) { Grow(1); Append(c); } // If the original array passed by the constructor wasn't enough // we allocate an array of a necessary size from the pool of free arrays // It would be ideal if the algorithm considered // discreteness of array size to avoid pool fragmentation. [MethodImpl(MethodImplOptions.NoInlining)] private void Grow(int requiredAdditionalCapacity) { Debug.Assert(requiredAdditionalCapacity > _chars.Length - _pos); char[] poolArray = ArrayPool<char>.Shared.Rent(Math.Max(_pos + requiredAdditionalCapacity, _chars.Length * 2)); _chars.CopyTo(poolArray); char[] toReturn = _arrayToReturnToPool; _chars = _arrayToReturnToPool = poolArray; if (toReturn != null) { ArrayPool<char>.Shared.Return(toReturn); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void Clear() { char[] toReturn = _arrayToReturnToPool; this = default; // for safety, to avoid using pooled array if this instance is erroneously appended to again if (toReturn != null) { ArrayPool<char>.Shared.Return(toReturn); } } // Missing methods: the situation is crystal clear private void AppendSlow(string s); public bool TryCopyTo(Span<char> destination, out int charsWritten); public void Append(string s); public void Append(char c, int count); public unsafe void Append(char* value, int length); public Span<char> AppendSpan(int length); }
рдпрд╣ рд╡рд░реНрдЧ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд░реВрдк рд╕реЗ рдЕрдкрдиреЗ рд╡рд░рд┐рд╖реНрда рд╕рд╛рдереА StringBuilder
рд╕рдорд╛рди рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рдФрд░ рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реИ: рдпрд╣ рдПрдХ рдореВрд▓реНрдп рдкреНрд░рдХрд╛рд░ рд╣реИред рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдореВрд▓реНрдп рджреНрд╡рд╛рд░рд╛ рд╕рдВрдЧреНрд░рд╣реАрдд рдФрд░ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрдХ рдирдпрд╛ ref
рдкреНрд░рдХрд╛рд░ рд╕рдВрд╢реЛрдзрдХ, рдЬреЛ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреА рдШреЛрд╖рдгрд╛ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХрд╛ рдПрдХ рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ, рдпрд╣ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдмрд╛рдзрд╛ рд╣реИ: рдЗрд╕реЗ рдХреЗрд╡рд▓ рд╕реНрдЯреИрдХ рдкрд░ рдЖрд╡рдВрдЯрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдореЗрд░рд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдХрдХреНрд╖рд╛ рдХреНрд╖реЗрддреНрд░реЛрдВ рдореЗрдВ рдЗрд╕рдХреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рд╕реЗ рддреНрд░реБрдЯрд┐ рдкреИрджрд╛ рд╣реЛрдЧреАред рдпрд╣ рд╕рдм рдХрд┐рд╕ рдЪреАрдЬ рдХреЗ рд▓рд┐рдП рд╣реИ? рдЗрд╕ рдкреНрд░рд╢реНрди рдХрд╛ рдЙрддреНрддрд░ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдмрд╕ StringBuilder
рд╡рд░реНрдЧ рдХреЛ рджреЗрдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рд╕рд╛рд░ рд╣рдордиреЗ рдЕрднреА рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рд╣реИ:
StringBuilder рд╡рд░реНрдЧ /src/mscorlib/src/System/Text/StringBuilder.cs
public sealed class StringBuilder : ISerializable { // A StringBuilder is internally represented as a linked list of blocks each of which holds // a chunk of the string. It turns out string as a whole can also be represented as just a chunk, // so that is what we do. internal char[] m_ChunkChars; // The characters in this block internal StringBuilder m_ChunkPrevious; // Link to the block logically before this block internal int m_ChunkLength; // The index in m_ChunkChars that represent the end of the block internal int m_ChunkOffset; // The logical offset (sum of all characters in previous blocks) internal int m_MaxCapacity = 0; // ... internal const int DefaultCapacity = 16;
StringBuilder
рдПрдХ рд╡рд░реНрдЧ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╡рд░реНрдгреЛрдВ рдХреА рдПрдХ рд╕рд░рдгреА рдХрд╛ рд╕рдВрджрд░реНрдн рд╣реЛрддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЬрдм рдЖрдк рдЗрд╕реЗ рдмрдирд╛рддреЗ рд╣реИрдВ, рддреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рджреЛ рдСрдмреНрдЬреЗрдХреНрдЯ рджрд┐рдЦрд╛рдИ рджреЗрддреЗ рд╣реИрдВ: StringBuilder
рдФрд░ рдкрд╛рддреНрд░реЛрдВ рдХреА рдПрдХ рд╕рд░рдгреА рдЬреЛ рдЖрдХрд╛рд░ рдореЗрдВ рдХрдо рд╕реЗ рдХрдо 16 рдЕрдХреНрд╖рд░ рд╣реИред рдпрд╣реА рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреА рдЕрдкреЗрдХреНрд╖рд┐рдд рд▓рдВрдмрд╛рдИ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИ: рдпрд╣ 16 рдЕрдХреНрд╖рд░реЛрдВ рдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЗ рд╕рд╛рде рд╕рд░рдгрд┐рдпреЛрдВ рдХреА рдПрдХрд▓ рд▓рд┐рдВрдХ рд╕реВрдЪреА рдЙрддреНрдкрдиреНрди рдХрд░рдХреЗ рдмрдирд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ, рдпрд╣ рдПрдХ рдмреЗрдХрд╛рд░ рд╣реИред ValueStringBuilder
рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ, рдЗрд╕рдХрд╛ рдорддрд▓рдм рдХреЛрдИ рдбрд┐рдлрд╝реЙрд▓реНрдЯ capacity
рдирд╣реАрдВ capacity
, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдмрд╛рд╣рд░реА рдореЗрдореЛрд░реА рдХреЛ рдЙрдзрд╛рд░ рд▓реЗрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рдПрдХ рдореВрд▓реНрдп рдкреНрд░рдХрд╛рд░ рд╣реИ, рдФрд░ рдпрд╣ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рд╕реНрдЯреИрдХ рдкрд░ рдкрд╛рддреНрд░реЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрдлрд░ рдЖрд╡рдВрдЯрд┐рдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкреВрд░рд╛ рдЙрджрд╛рд╣рд░рдг рдЕрдкрдиреА рд╕рд╛рдордЧреНрд░реА рдХреЗ рд╕рд╛рде рдвреЗрд░ рдкрд░ рд░рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЕрдиреБрдХреВрд▓рди рдХрд╛ рдореБрджреНрджрд╛ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЬреИрд╕реЗ рд╣реАрдк рдкрд░ рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдвреЗрд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рдХрдореА рдХреЗ рд╕рд╛рде рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИред рддреЛ, рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдкреНрд░рд╢реНрди рд╣реЛ рд╕рдХрддрд╛ рд╣реИ: рд╣рдо рд╣рдореЗрд╢рд╛ ValueStringBuilder
(рдпрд╛ рдЗрд╕рдХреЗ рдХрд╕реНрдЯрдо рдПрдирд╛рд▓реЙрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдХрд░рддреЗ рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдореВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЖрдВрддрд░рд┐рдХ рд╣реИ)? рдЙрддреНрддрд░ рд╣реИ: рдпрд╣ рдПрдХ рдХрд╛рд░реНрдп рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред рдХреНрдпрд╛ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХрд╛ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдЖрдХрд╛рд░ рд╣реЛрдЧрд╛? рдХреНрдпрд╛ рдЗрд╕рдХреА рдЕрдзрд┐рдХрддрдо рдЬреНрдЮрд╛рдд рд▓рдВрдмрд╛рдИ рд╣реЛрдЧреА? рдпрджрд┐ рдЖрдк "рд╣рд╛рдВ" рдХрд╛ рдЬрд╡рд╛рдм рджреЗрддреЗ рд╣реИрдВ рдФрд░ рдпрджрд┐ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдЙрдЪрд┐рдд рд╕реАрдорд╛рдУрдВ рд╕реЗ рдЕрдзрд┐рдХ рдирд╣реАрдВ рд╣реИ, рддреЛ рдЖрдк рд╕реНрдЯреНрд░рд┐рдВрдЧрдмреНрдпреВрд╕реНрдЯ рдХреЗ рдорд╛рди рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрджрд┐ рдЖрдк рд▓рдВрдмреЗ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╕рд╛рдорд╛рдиреНрдп рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред
ValueListBuilder
internal ref partial struct ValueListBuilder<T> { private Span<T> _span; private T[] _arrayFromPool; private int _pos; public ValueListBuilder(Span<T> initialSpan) { _span = initialSpan; _arrayFromPool = null; _pos = 0; } public int Length { get; set; } public ref T this[int index] { get; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Append(T item); public ReadOnlySpan<T> AsSpan(); [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose(); private void Grow(); }
рджреВрд╕рд░реЗ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдбреЗрдЯрд╛ рдЬрд┐рд╕реЗ рдореИрдВ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдиреЛрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рд╡рд╣ рд╣реИ ValueListBuilder
рдкреНрд░рдХрд╛рд░ред рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рддрдм рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рдЖрдкрдХреЛ рдереЛрдбрд╝реЗ рд╕рдордп рдХреЗ рд▓рд┐рдП рддрддреНрд╡реЛрдВ рдХрд╛ рд╕рдВрдЧреНрд░рд╣ рдмрдирд╛рдиреЗ рдФрд░ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЛ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ, рдпрд╣ рдХрд╛рд░реНрдп ValueStringBuilder
рдХрд╛рд░реНрдп рдХреЗ рд╕рдорд╛рди рд╣реИред рдФрд░ рдЗрд╕реЗ рдЗрд╕реА рддрд░рд╣ рд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
рдлрд╝рд╛рдЗрд▓ ValueListBuilder.cs coreclr / src /../ рд╕рд╛рдорд╛рдиреНрдп / ValueListBuilder.cs
рдЗрд╕реЗ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдХрд╣рдиреЗ рдХреЗ рд▓рд┐рдП, рдпреЗ рд╕реНрдерд┐рддрд┐рдпрд╛рдВ рдЕрдХреНрд╕рд░ рд╣реЛрддреА рд╣реИрдВред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдкрд╣рд▓реЗ рд╣рдордиреЗ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рджреВрд╕рд░реЗ рддрд░реАрдХреЗ рд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛ред рд╣рдо рдПрдХ List
рдмрдирд╛рддреЗ рдереЗ, рдЙрд╕реЗ рдбреЗрдЯрд╛ рд╕реЗ рднрд░рддреЗ рдереЗ рдФрд░ рдЙрд╕рдХрд╛ рд╕рдВрджрд░реНрдн рдЦреЛ рджреЗрддреЗ рдереЗред рдпрджрд┐ рд╡рд┐рдзрд┐ рдХреЛ рдЕрдХреНрд╕рд░ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдПрдХ рджреБрдЦрдж рд╕реНрдерд┐рддрд┐ рдХреЛ рдЬрдиреНрдо рджреЗрдЧрд╛: рдХрдИ List
рдЙрджрд╛рд╣рд░рдг (рдФрд░ рд╕рдВрдмрджреНрдз рд╕рд░рдгрд┐рдпрд╛рдБ) рдвреЗрд░ рдкрд░ рдирд┐рд▓рдВрдмрд┐рдд рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВред рдЕрдм рдпрд╣ рд╕рдорд╕реНрдпрд╛ рд╣рд▓ рд╣реЛ рдЧрдИ рд╣реИ: рдХреЛрдИ рдЕрддрд┐рд░рд┐рдХреНрдд рдСрдмреНрдЬреЗрдХреНрдЯ рдирд╣реАрдВ рдмрдирд╛рдП рдЬрд╛рдПрдВрдЧреЗред рд╣рд╛рд▓рд╛рдБрдХрд┐, ValueStringBuilder
рдорд╛рдорд▓реЗ рдореЗрдВ рдпрд╣ рдХреЗрд╡рд▓ Microsoft рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЗ рд▓рд┐рдП рд╣рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ: рдЗрд╕ рд╡рд░реНрдЧ рдореЗрдВ internal
рд╕рдВрд╢реЛрдзрдХ рд╣реИред
рдирд┐рдпрдо рдФрд░ рдЙрдкрдпреЛрдЧ рдЕрднреНрдпрд╛рд╕
рдирдП рдкреНрд░рдХрд╛рд░ рдХреЗ рдбреЗрдЯрд╛ рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдЗрд╕рдХреЗ рд╕рд╛рде рджреЛ рдпрд╛ рддреАрди рдпрд╛ рдмреЗрд╣рддрд░ рддрд░реАрдХреЗ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЕрднреА рдореБрдЦреНрдп рдирд┐рдпрдо рд╕реАрдЦрдирд╛ рд╕рдВрднрд╡ рд╣реИ:
- рдпрджрд┐ рдЖрдкрдХреА рд╡рд┐рдзрд┐ рдХреБрдЫ рдЗрдирдкреБрдЯ рдбреЗрдЯрд╛рд╕реЗрдЯ рдХреЛ рдЙрд╕рдХреЗ рдЖрдХрд╛рд░ рдХреЛ рдмрджрд▓реЗ рдмрд┐рдирд╛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рддреА рд╣реИ, рддреЛ рдЖрдк
Span
рдкреНрд░рдХрд╛рд░ рд╕реЗ рдЪрд┐рдкрдХрдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрджрд┐ рдЖрдк рдмрдлрд░ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдирд╣реАрдВ рдХрд░рдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ, рддреЛ ReadOnlySpan
рдкреНрд░рдХрд╛рд░ рдЪреБрдиреЗрдВ; - рдпрджрд┐ рдЖрдкрдХреА рд╡рд┐рдзрд┐ рдХреБрдЫ рдЖрдБрдХрдбрд╝реЛрдВ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рддрд╛рд░реЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рддреА рд╣реИ рдпрд╛ рдЗрди рддрд╛рд░реЛрдВ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░ рд░рд╣реА рд╣реИ, рддреЛ рдЗрд╕реЗ
ReadOnlySpan<char>
рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП ред рдирдпрд╛ рдирд┐рдпрдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдХреНрдпреЛрдВрдХрд┐ рдЬрдм рдЖрдк рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдХрд┐рд╕реА рдХреЛ рдЖрдкрдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рдХрд▓реНрдк рдмрдирд╛рддреЗ рд╣реИрдВ; - рдпрджрд┐ рдЖрдкрдХреЛ рдХрд┐рд╕реА рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рдЫреЛрдЯрд╛ рдбреЗрдЯрд╛ рд╕рд░рдгреА (10 kB рд╕реЗ рдЕрдзрд┐рдХ рдирд╣реАрдВ) рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЖрдк рдЖрд╕рд╛рдиреА рд╕реЗ
Span<TType> buf = stackalloc TType[size]
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡реНрдпрд╡рд╕реНрдерд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ TType рдПрдХ рдореВрд▓реНрдп рдкреНрд░рдХрд╛рд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдХреНрдпреЛрдВрдХрд┐ stackalloc
рдХреЗрд╡рд▓ рдореВрд▓реНрдп рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
рдЕрдиреНрдп рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдЖрдк рдмреЗрд╣рддрд░ Memory
рдкрд░ рдХрд░реАрдм рд╕реЗ рджреЗрдЦреЗрдВрдЧреЗ рдпрд╛ рдХреНрд▓рд╛рд╕рд┐рдХ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред
рд╕реНрдкреИрди рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ?
рдореИрдВ рдХреБрдЫ рдЕрддрд┐рд░рд┐рдХреНрдд рд╢рдмреНрдж рдХрд╣рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдХрд┐ Span
рдХреИрд╕реЗ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИ рдФрд░ рдпрд╣ рдХреНрдпреЛрдВ рдЙрд▓реНрд▓реЗрдЦрдиреАрдп рд╣реИред рдФрд░ рдХреБрдЫ рдмрд╛рдд рдХрд░рдиреА рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреЗ рдбреЗрдЯрд╛ рдХреЗ рджреЛ рд╕рдВрд╕реНрдХрд░рдг рд╣реИрдВ: рдПрдХ .NET рдХреЛрд░ 2.0+ рдХреЗ рд▓рд┐рдП рдФрд░ рджреВрд╕рд░рд╛ рд╢реЗрд╖ рдХреЗ рд▓рд┐рдПред
рдлрд╝рд╛рдЗрд▓ Span.Fast.cs, .NET рдХреЛрд░ 2.0 coreclr /... / рд╕рд┐рд╕реНрдЯрдо / Span.Fast.cs **
public readonly ref partial struct Span<T> { /// A reference to a .NET object or a pure pointer internal readonly ByReference<T> _pointer; /// The length of the buffer based on the pointer private readonly int _length; // ... }
рдлрд╝рд╛рдЗрд▓ ??? [Decompiled]
public ref readonly struct Span<T> { private readonly System.Pinnable<T> _pinnable; private readonly IntPtr _byteOffset; private readonly int _length; // ... }
рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рд╡рд┐рд╢рд╛рд▓ .NET рдлреНрд░реЗрдорд╡рд░реНрдХ рдФрд░ .NET рдХреЛрд░ 1. * рдореЗрдВ рдХреВрдбрд╝реЗ рдХреЗ рд╕рдВрдЧреНрд░рд╛рд╣рдХ рдХреЛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рддрд░реАрдХреЗ рд╕реЗ рдЕрджреНрдпрддрди рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ (.NET рдХреЛрд░ 2.0+ рдХреЗ рд╡рд┐рдкрд░реАрдд) рдФрд░ рдЙрдиреНрд╣реЗрдВ рдмрдлрд░ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕реВрдЪрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ, рдХрд┐ рдЖрдВрддрд░рд┐рдХ рд░реВрдк рд╕реЗ Span
рдкреНрд░рдмрдВрдзрд┐рдд .NET рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИ рдЬреИрд╕реЗ рдХрд┐ рд╡реЗ рдЕрдкреНрд░рдмрдВрдзрд┐рдд рд╣реИрдВред рдмрд╕ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рджреВрд╕рд░реЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рджреЗрдЦреЗрдВ: рдЗрд╕рдХреЗ рддреАрди рдХреНрд╖реЗрддреНрд░ рд╣реИрдВред рдкрд╣рд▓реЗ рд╡рд╛рд▓рд╛ рдПрдХ manged рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рд╕рдВрджрд░реНрдн рд╣реИред рдЗрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗ рджреВрд╕рд░рд╛ рдПрдХ рдмрд╛рдЗрдЯреНрд╕ рдореЗрдВ рдСрдлрд╕реЗрдЯ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдбреЗрдЯрд╛ рдмрдлрд░ рдХреА рд╢реБрд░реБрдЖрдд рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдЗрд╕ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдореЗрдВ char
рд╡рд░реНрдг рд╣реЛрддреЗ рд╣реИрдВ рдЬрдмрдХрд┐ рд╕рд░рдгрд┐рдпреЛрдВ рдореЗрдВ рдЗрд╕рдореЗрдВ рдПрдХ рд╕рд░рдгреА рдХрд╛ рдбреЗрдЯрд╛ рд╣реЛрддрд╛ рд╣реИ)ред рдЕрдВрдд рдореЗрдВ, рддреАрд╕рд░реЗ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдПрдХ рдкрдВрдХреНрддрд┐ рдореЗрдВ рд░рдЦреА рдЧрдИ рдмрдлрд░ рдореЗрдВ рддрддреНрд╡реЛрдВ рдХреА рдорд╛рддреНрд░рд╛ рд╣реЛрддреА рд╣реИред
рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ Span
рдХреИрд╕реЗ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:
рдлрд╝рд╛рдЗрд▓ рдореЗрдореЛрд░реАрдПрдХреНрд╕реНрдЯреЗрдВрд╢рди.рдлрд╝рд╛рд╕реНрдЯ.рд╕реНрдХ
coreclr /../ MemoryExtensions.Fast.cs
public static ReadOnlySpan<char> AsSpan(this string text) { if (text == null) return default; return new ReadOnlySpan<char>(ref text.GetRawStringData(), text.Length); }
рдЬрд╣рд╛рдВ string.GetRawStringData()
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рддрд░реАрдХреЗ рд╕реЗ рджрд┐рдЦрддрд╛ рд╣реИ:
рдлрд╝реАрд▓реНрдб рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЗ рд╕рд╛рде рдПрдХ рдлрд╝рд╛рдЗрд▓ coreclr /../ рд╕рд┐рд╕реНрдЯрдо / String.CoreCLR.cs
GetRawStringData coreclr /../ рд╕рд┐рд╕реНрдЯрдо / String.cs рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЗ рд╕рд╛рде рдПрдХ рдлрд╝рд╛рдЗрд▓
public sealed partial class String : IComparable, IEnumerable, IConvertible, IEnumerable<char>, IComparable<string>, IEquatable<string>, ICloneable { // // These fields map directly onto the fields in an EE StringObject. See object.h for the layout. // [NonSerialized] private int _stringLength; // For empty strings, this will be '\0' since // strings are both null-terminated and length prefixed [NonSerialized] private char _firstChar; internal ref char GetRawStringData() => ref _firstChar; }
рдпрд╣ рд╡рд┐рдзрд┐ рдХреЛ рд╕реАрдзреЗ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рдЕрдВрджрд░ рддрдХ рдкрд╣реБрдВрдЪрд╛рддрд╛ рд╣реИ, рдЬрдмрдХрд┐ ref char
рд╡рд┐рдирд┐рд░реНрджреЗрд╢ рдЬреАрд╕реА рдХреЗ рд╕рдХреНрд░рд┐рдп рд╣реЛрдиреЗ рдкрд░ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд╕рд╛рде рдЗрд╕реЗ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдХреЗ рдЬреАрд╕реА рдХреЛ рдПрдХ рдЕрдкреНрд░рдмрдВрдзрд┐рдд рд╕рдВрджрд░реНрдн рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
рдПрдХ рд╣реА рдмрд╛рдд рд╕рд░рдгрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рд╣реИ: рдЬрдм Span
рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдХреБрдЫ рдЖрдВрддрд░рд┐рдХ рдЬреЗрдЖрдИрдЯреА рдХреЛрдб рдбреЗрдЯрд╛ рд╕рд░рдгреА рдХреА рд╢реБрд░реБрдЖрдд рдХреЗ рд▓рд┐рдП рдСрдлрд╕реЗрдЯ рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕ рдСрдлрд╕реЗрдЯ рдХреЗ рд╕рд╛рде Span
рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рддрд╛ рд╣реИред рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ рдЖрдк рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдФрд░ рд╕рд░рдгрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдСрдлрд╕реЗрдЯ рдХреА рдЧрдгрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрд╕ рдкрд░ рд╕реНрдореГрддрд┐ ((ред \ ObjectsStructure.md) рдореЗрдВ рд╡рд╕реНрддреБрдУрдВ рдХреА рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзреНрдпрд╛рдп рдореЗрдВ рдЪрд░реНрдЪрд╛ рдХреА рдЧрдИ рдереАред
рджрд┐рдП рдЧрдП рдорд╛рди рдХреЗ рд░реВрдк рдореЗрдВ рд╕реНрдкреИрди <рдЯреА>
рд╕рднреА рд╕рджреНрднрд╛рд╡ рдХреЗ рдмрд╛рд╡рдЬреВрдж, Span
рдореЗрдВ рдПрдХ рд╡рд┐рдзрд┐ рд╕реЗ рд╡рд╛рдкрд╕реА рдкрд░ рдХреБрдЫ рддрд╛рд░реНрдХрд┐рдХ рд▓реЗрдХрд┐рди рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд рдмрд╛рдзрд╛рдПрдВ рд╣реИрдВред рдпрджрд┐ рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рджреЗрдЦреЗрдВ:
unsafe void Main() { var x = GetSpan(); } public Span<byte> GetSpan() { Span<byte> reff = new byte[100]; return reff; }
рд╣рдо рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рддрд╛рд░реНрдХрд┐рдХ рдФрд░ рдЕрдЪреНрдЫрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрджрд┐ рд╣рдо рдПрдХ рдирд┐рд░реНрджреЗрд╢ рдХреЛ рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ:
unsafe void Main() { var x = GetSpan(); } public Span<byte> GetSpan() { Span<byte> reff = stackalloc byte[100]; return reff; }
рдПрдХ рдХрдВрдкрд╛рдЗрд▓рд░ рдЗрд╕реЗ рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдХрд░реЗрдЧрд╛ред рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рдореИрдВ рдХреНрдпреЛрдВ рдХрд╣реВрдВ, рдореИрдВ рдЖрдкрдХреЛ рдпрд╣ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдХрд┐ рдпрд╣ рдирд┐рд░реНрдорд╛рдг рдХрд┐рди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд▓рд╛рддрд╛ рд╣реИред
рдЦреИрд░, рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдЖрдкрдиреЗ рд╕реЛрдЪрд╛ рдерд╛, рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдпрд╛ рдерд╛ рдФрд░ рд╢рд╛рдпрдж рдЗрд╕рдХрд╛ рдХрд╛рд░рдг рднреА рд╕рдордЭрд╛ рд╣реЛрдЧрд╛ред рдпрджрд┐ рд╣рд╛рдБ, рддреЛ [рдереНрд░реЗрдб рд╕реНрдЯреИрдХ] (./hreadStack.md) рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рд╡рд┐рд╕реНрддреГрдд рдЕрдзреНрдпрд╛рдп рд▓рд┐рдЦрдиреЗ рдХреЗ рдореЗрд░реЗ рдкреНрд░рдпрд╛рд╕реЛрдВ рдХрд╛ рднреБрдЧрддрд╛рди рдХрд┐рдпрд╛ рдЧрдпрд╛ред рдХреНрдпреЛрдВрдХрд┐ рдЬрдм рдЖрдк рдЕрдкрдиреЗ рдХрд╛рдо рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рд╡рд╛рд▓реА рд╡рд┐рдзрд┐ рд╕реЗ рд╕реНрдерд╛рдиреАрдп рдЪрд░ рдХрд╛ рд╕рдВрджрд░реНрдн рджреЗрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдХрд┐рд╕реА рдЕрдиреНрдп рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рддрдм рддрдХ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВ рдЬрдм рддрдХ рдХрд┐ рд╡рд╣ рдЕрдкрдирд╛ рдХрд╛рдо рдкреВрд░рд╛ рди рдХрд░ рд▓реЗ, рдФрд░ рдлрд┐рд░ x [0.99] рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЙрди рд╕реНрдерд╛рдиреАрдп рдЪрд░ рдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреЛ рдкрдврд╝реЗрдВред
рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдЬрдм рд╣рдо рдЗрд╕ рддрд░рд╣ рдХреЗ рдХреЛрдб рдХреЛ рдЪреЗрддрд╛рд╡рдиреА рджреЗрдХрд░ рд╣рдорд╛рд░реА рдХрд▓рд╛рдИ рдкрд░ CS8352 Cannot use local 'reff' in this context because it may expose referenced variables outside of their declaration scope
рджреЗрдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ: CS8352 Cannot use local 'reff' in this context because it may expose referenced variables outside of their declaration scope
ред рдХрдВрдкрд╛рдЗрд▓рд░ рд╕рд╣реА рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрджрд┐ рдЖрдк рдЗрд╕ рддреНрд░реБрдЯрд┐ рдХреЛ рдмрд╛рдпрдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдПрдХ рдореМрдХрд╛ рд╣реЛрдЧрд╛, рдЬрдмрдХрд┐ рдПрдХ рдкреНрд▓рдЧ-рдЗрди рдореЗрдВ, рджреВрд╕рд░реЛрдВ рдХреЗ рдкрд╛рд╕рд╡рд░реНрдб рдЪреЛрд░реА рдХрд░рдиреЗ рдпрд╛ рд╣рдорд╛рд░реЗ рдкреНрд▓рдЧ-рдЗрди рдХреЛ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖рд╛рдзрд┐рдХрд╛рд░реЛрдВ рдХреЛ рдмрдврд╝рд╛рдиреЗ рдХреЗ рд▓рд┐рдПред
рдпрд╣ рдЕрдзреНрдпрд╛рдп рд░реВрд╕реА рд╕реЗ рд╕рдВрдпреБрдХреНрдд рд░реВрдк рд╕реЗ рд▓реЗрдЦрдХ рджреНрд╡рд╛рд░рд╛ рдФрд░ рдкреЗрд╢реЗрд╡рд░ рдЕрдиреБрд╡рд╛рджрдХреЛрдВ рджреНрд╡рд╛рд░рд╛ рдЕрдиреБрд╡рд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ ред рдЖрдк рд░реВрд╕реА рдпрд╛ рдЕрдВрдЧреНрд░реЗрдЬреА рд╕реЗ рдХрд┐рд╕реА рдЕрдиреНрдп рднрд╛рд╖рд╛ рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХрд░рдиреЗ рдореЗрдВ рд╣рдорд╛рд░реА рдорджрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдореБрдЦреНрдпрддрдГ рдЪреАрдиреА рдпрд╛ рдЬрд░реНрдорди рдореЗрдВред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрджрд┐ рдЖрдк рд╣рдореЗрдВ рдзрдиреНрдпрд╡рд╛рдж рджреЗрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рдпрд╣ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдореЗрдВ рдЧрд┐рддреБрдм рдкрд░ рдПрдХ рд╕реНрдЯрд╛рд░ рджреЗрдирд╛ рд╣реИ рдпрд╛ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЛ рдлреЛрд░реНрдХ рдХрд░рдирд╛ рд╣реИ
github / sidristij / dotnetbook ред