5
5
//
6
6
//
7
7
//
8
- // Description: Contains the ThicknessConverter: TypeConverter for the Thicknessclass .
8
+ // Description: Contains the ThicknessConverter: TypeConverter for the Thickness struct .
9
9
//
10
10
//
11
11
12
12
using System ;
13
13
using System . ComponentModel ;
14
14
using System . ComponentModel . Design . Serialization ;
15
+ using System . Runtime . CompilerServices ;
15
16
using System . Globalization ;
16
17
using System . Reflection ;
17
18
using System . Text ;
@@ -73,15 +74,7 @@ public override bool CanConvertFrom(ITypeDescriptorContext typeDescriptorContext
73
74
public override bool CanConvertTo ( ITypeDescriptorContext typeDescriptorContext , Type destinationType )
74
75
{
75
76
// We can convert to an InstanceDescriptor or to a string.
76
- if ( destinationType == typeof ( InstanceDescriptor )
77
- || destinationType == typeof ( string ) )
78
- {
79
- return true ;
80
- }
81
- else
82
- {
83
- return false ;
84
- }
77
+ return destinationType == typeof ( InstanceDescriptor ) || destinationType == typeof ( string ) ;
85
78
}
86
79
87
80
/// <summary>
@@ -102,20 +95,22 @@ public override bool CanConvertTo(ITypeDescriptorContext typeDescriptorContext,
102
95
/// <param name="source"> The object to convert to a Thickness. </param>
103
96
public override object ConvertFrom ( ITypeDescriptorContext typeDescriptorContext , CultureInfo cultureInfo , object source )
104
97
{
105
- if ( source != null )
106
- {
107
- if ( source is string ) { return FromString ( ( string ) source , cultureInfo ) ; }
108
- else if ( source is double ) { return new Thickness ( ( double ) source ) ; }
109
- else { return new Thickness ( Convert . ToDouble ( source , cultureInfo ) ) ; }
110
- }
111
- throw GetConvertFromException ( source ) ;
98
+ if ( source is null )
99
+ throw GetConvertFromException ( source ) ;
100
+
101
+ if ( source is string sourceString )
102
+ return FromString ( sourceString , cultureInfo ) ;
103
+ else if ( source is double sourceValue )
104
+ return new Thickness ( sourceValue ) ;
105
+ else
106
+ return new Thickness ( Convert . ToDouble ( source , cultureInfo ) ) ;
112
107
}
113
108
114
109
/// <summary>
115
110
/// ConvertTo - Attempt to convert a Thickness to the given type
116
111
/// </summary>
117
112
/// <returns>
118
- /// The object which was constructoed .
113
+ /// The object which was constructed .
119
114
/// </returns>
120
115
/// <exception cref="ArgumentNullException">
121
116
/// An ArgumentNullException is thrown if the example object is null.
@@ -133,22 +128,18 @@ public override object ConvertTo(ITypeDescriptorContext typeDescriptorContext, C
133
128
ArgumentNullException . ThrowIfNull ( value ) ;
134
129
ArgumentNullException . ThrowIfNull ( destinationType ) ;
135
130
136
- if ( ! ( value is Thickness ) )
137
- {
138
- #pragma warning suppress 6506 // value is obviously not null
139
- throw new ArgumentException ( SR . Format ( SR . UnexpectedParameterType , value . GetType ( ) , typeof ( Thickness ) ) , "value" ) ;
140
- }
131
+ if ( value is not Thickness thickness )
132
+ throw new ArgumentException ( SR . Format ( SR . UnexpectedParameterType , value . GetType ( ) , typeof ( Thickness ) ) , nameof ( value ) ) ;
141
133
142
- Thickness th = ( Thickness ) value ;
143
- if ( destinationType == typeof ( string ) ) { return ToString ( th , cultureInfo ) ; }
144
- if ( destinationType == typeof ( InstanceDescriptor ) )
134
+ if ( destinationType == typeof ( string ) )
135
+ return ToString ( thickness , cultureInfo ) ;
136
+ else if ( destinationType == typeof ( InstanceDescriptor ) )
145
137
{
146
138
ConstructorInfo ci = typeof ( Thickness ) . GetConstructor ( new Type [ ] { typeof ( double ) , typeof ( double ) , typeof ( double ) , typeof ( double ) } ) ;
147
- return new InstanceDescriptor ( ci , new object [ ] { th . Left , th . Top , th . Right , th . Bottom } ) ;
139
+ return new InstanceDescriptor ( ci , new object [ ] { thickness . Left , thickness . Top , thickness . Right , thickness . Bottom } ) ;
148
140
}
149
141
150
142
throw new ArgumentException ( SR . Format ( SR . CannotConvertType , typeof ( Thickness ) , destinationType . FullName ) ) ;
151
-
152
143
}
153
144
154
145
@@ -162,60 +153,70 @@ public override object ConvertTo(ITypeDescriptorContext typeDescriptorContext, C
162
153
163
154
#region Internal Methods
164
155
165
- static internal string ToString ( Thickness th , CultureInfo cultureInfo )
156
+ /// <summary>
157
+ /// Converts <paramref name="th"/> to its string representation using the specified <paramref name="cultureInfo"/>.
158
+ /// </summary>
159
+ /// <param name="th">The <see cref="Thickness"/> to convert to string.</param>
160
+ /// <param name="cultureInfo">Culture to use when formatting doubles and choosing separator.</param>
161
+ /// <returns>The formatted <paramref name="th"/> as string using the specified <paramref name="cultureInfo"/>.</returns>
162
+ internal static string ToString ( Thickness th , CultureInfo cultureInfo )
166
163
{
167
164
char listSeparator = TokenizerHelper . GetNumericListSeparator ( cultureInfo ) ;
168
165
169
166
// Initial capacity [64] is an estimate based on a sum of:
170
167
// 48 = 4x double (twelve digits is generous for the range of values likely)
171
168
// 8 = 4x Unit Type string (approx two characters)
172
- // 4 = 4x separator characters
173
- StringBuilder sb = new StringBuilder ( 64 ) ;
174
-
175
- sb . Append ( LengthConverter . ToString ( th . Left , cultureInfo ) ) ;
176
- sb . Append ( listSeparator ) ;
177
- sb . Append ( LengthConverter . ToString ( th . Top , cultureInfo ) ) ;
178
- sb . Append ( listSeparator ) ;
179
- sb . Append ( LengthConverter . ToString ( th . Right , cultureInfo ) ) ;
180
- sb . Append ( listSeparator ) ;
181
- sb . Append ( LengthConverter . ToString ( th . Bottom , cultureInfo ) ) ;
182
- return sb . ToString ( ) ;
169
+ // 3 = 3x separator characters
170
+ // 1 = 1x scratch space for alignment
171
+
172
+ DefaultInterpolatedStringHandler handler = new ( 0 , 7 , cultureInfo , stackalloc char [ 64 ] ) ;
173
+ LengthConverter . FormatLengthAsString ( th . Left , ref handler ) ;
174
+ handler . AppendFormatted ( listSeparator ) ;
175
+
176
+ LengthConverter . FormatLengthAsString ( th . Top , ref handler ) ;
177
+ handler . AppendFormatted ( listSeparator ) ;
178
+
179
+ LengthConverter . FormatLengthAsString ( th . Right , ref handler ) ;
180
+ handler . AppendFormatted ( listSeparator ) ;
181
+
182
+ LengthConverter . FormatLengthAsString ( th . Bottom , ref handler ) ;
183
+
184
+ return handler . ToStringAndClear ( ) ;
183
185
}
184
186
185
- static internal Thickness FromString ( string s , CultureInfo cultureInfo )
187
+ /// <summary>
188
+ /// Constructs a <see cref="Thickness"/> struct out of string representation supplied by <paramref name="s"/> and the specified <paramref name="cultureInfo"/>.
189
+ /// </summary>
190
+ /// <param name="s">The string representation of a <see cref="Thickness"/> struct.</param>
191
+ /// <param name="cultureInfo">The <see cref="CultureInfo"/> which was used to format this string.</param>
192
+ /// <returns>A new instance of <see cref="Thickness"/> struct representing the data contained in <paramref name="s"/>.</returns>
193
+ /// <exception cref="FormatException">Thrown when <paramref name="s"/> contains invalid string representation.</exception>
194
+ internal static Thickness FromString ( string s , CultureInfo cultureInfo )
186
195
{
187
- TokenizerHelper th = new TokenizerHelper ( s , cultureInfo ) ;
188
- double [ ] lengths = new double [ 4 ] ;
196
+ TokenizerHelper th = new ( s , cultureInfo ) ;
197
+ Span < double > lengths = stackalloc double [ 4 ] ;
189
198
int i = 0 ;
190
199
191
200
// Peel off each double in the delimited list.
192
201
while ( th . NextToken ( ) )
193
202
{
194
- if ( i >= 4 )
195
- {
196
- i = 5 ; // Set i to a bad value.
197
- break ;
198
- }
203
+ if ( i >= 4 ) // In case we've got more than 4 doubles, we throw
204
+ throw new FormatException ( SR . Format ( SR . InvalidStringThickness , s ) ) ;
199
205
200
206
lengths [ i ] = LengthConverter . FromString ( th . GetCurrentToken ( ) , cultureInfo ) ;
201
207
i ++ ;
202
208
}
203
209
204
- // We have a reasonable interpreation for one value (all four edges), two values (horizontal, vertical),
210
+ // We have a reasonable interpretation for one value (all four edges),
211
+ // two values (horizontal, vertical),
205
212
// and four values (left, top, right, bottom).
206
- switch ( i )
213
+ return i switch
207
214
{
208
- case 1 :
209
- return new Thickness ( lengths [ 0 ] ) ;
210
-
211
- case 2 :
212
- return new Thickness ( lengths [ 0 ] , lengths [ 1 ] , lengths [ 0 ] , lengths [ 1 ] ) ;
213
-
214
- case 4 :
215
- return new Thickness ( lengths [ 0 ] , lengths [ 1 ] , lengths [ 2 ] , lengths [ 3 ] ) ;
216
- }
217
-
218
- throw new FormatException ( SR . Format ( SR . InvalidStringThickness , s ) ) ;
215
+ 1 => new Thickness ( lengths [ 0 ] ) ,
216
+ 2 => new Thickness ( lengths [ 0 ] , lengths [ 1 ] , lengths [ 0 ] , lengths [ 1 ] ) ,
217
+ 4 => new Thickness ( lengths [ 0 ] , lengths [ 1 ] , lengths [ 2 ] , lengths [ 3 ] ) ,
218
+ _ => throw new FormatException ( SR . Format ( SR . InvalidStringThickness , s ) ) ,
219
+ } ;
219
220
}
220
221
221
222
#endregion
0 commit comments