3131// Official Documentation: https://gameframex.doc.alianblank.com/
3232// ==========================================================================================
3333
34+ using System . Collections . Concurrent ;
3435using System . Reflection ;
3536using GameFrameX . Foundation . Options . Attributes ;
3637
@@ -52,7 +53,7 @@ public class OptionsBuilder
5253 /// <returns>构建的配置选项对象</returns>
5354 public static TOptions Create < TOptions > ( string [ ] args , bool skipValidation = false ) where TOptions : class , new ( )
5455 {
55- var builder = new OptionsBuilder < TOptions > ( args ) ;
56+ var builder = new OptionsBuilder < TOptions > ( args ?? Array . Empty < string > ( ) ) ;
5657 return builder . Build ( skipValidation ) ;
5758 }
5859
@@ -73,7 +74,7 @@ public static TOptions Create<TOptions>(
7374 bool useEnvironmentVariables = true ,
7475 bool skipValidation = false ) where TOptions : class , new ( )
7576 {
76- var builder = new OptionsBuilder < TOptions > ( args , boolFormat , ensurePrefixedKeys , useEnvironmentVariables ) ;
77+ var builder = new OptionsBuilder < TOptions > ( args ?? Array . Empty < string > ( ) , boolFormat , ensurePrefixedKeys , useEnvironmentVariables ) ;
7778 return builder . Build ( skipValidation ) ;
7879 }
7980
@@ -86,7 +87,7 @@ public static TOptions Create<TOptions>(
8687 /// <returns>构建的配置选项对象</returns>
8788 public static TOptions CreateFromArgsOnly < TOptions > ( string [ ] args , bool skipValidation = false ) where TOptions : class , new ( )
8889 {
89- var builder = new OptionsBuilder < TOptions > ( args , useEnvironmentVariables : false ) ;
90+ var builder = new OptionsBuilder < TOptions > ( args ?? Array . Empty < string > ( ) , useEnvironmentVariables : false ) ;
9091 return builder . Build ( skipValidation ) ;
9192 }
9293
@@ -125,7 +126,7 @@ public static TOptions Create<TOptions>(
125126 {
126127 try
127128 {
128- result = Create < TOptions > ( args ) ;
129+ result = Create < TOptions > ( args ?? Array . Empty < string > ( ) ) ;
129130 error = null ;
130131 return true ;
131132 }
@@ -147,7 +148,7 @@ public static TOptions Create<TOptions>(
147148 public static TOptions CreateWithDebug < TOptions > ( string [ ] args , bool skipValidation = false ) where TOptions : class , new ( )
148149 {
149150 // 创建配置选项
150- var result = Create < TOptions > ( args , skipValidation ) ;
151+ var result = Create < TOptions > ( args ?? Array . Empty < string > ( ) , skipValidation ) ;
151152
152153 // 打印解析结果
153154 OptionsDebugger . PrintParsedOptions ( result ) ;
@@ -167,6 +168,23 @@ public static TOptions Create<TOptions>(
167168/// </remarks>
168169public sealed class OptionsBuilder < T > where T : class , new ( )
169170{
171+ /// <summary>
172+ /// 反射结果缓存,用于缓存类型的属性信息
173+ /// Reflection result cache for caching type property information
174+ /// </summary>
175+ private static readonly ConcurrentDictionary < Type , PropertyInfo [ ] > PropertyCache = new ( ) ;
176+
177+ /// <summary>
178+ /// 获取指定类型的所有属性(带缓存)
179+ /// Gets all properties of the specified type (with caching)
180+ /// </summary>
181+ /// <param name="type">要获取属性的类型 / The type to get properties for</param>
182+ /// <returns>属性信息数组 / Array of property information</returns>
183+ private static PropertyInfo [ ] GetCachedProperties ( Type type )
184+ {
185+ return PropertyCache . GetOrAdd ( type , t => t . GetProperties ( ) ) ;
186+ }
187+
170188 private readonly string [ ] _args ;
171189 private readonly bool _useEnvironmentVariables ;
172190 private readonly bool _ensurePrefixedKeys ;
@@ -267,7 +285,7 @@ public T Build(bool skipValidation = false)
267285 /// <param name="target">目标对象</param>
268286 private void ApplyDefaultValues ( T target )
269287 {
270- var properties = typeof ( T ) . GetProperties ( )
288+ var properties = GetCachedProperties ( typeof ( T ) )
271289 . Where ( p => p . CanWrite )
272290 . ToList ( ) ;
273291
@@ -310,7 +328,7 @@ private void ApplyDefaultValues(T target)
310328 /// <param name="target">目标对象</param>
311329 private void ValidateRequiredOptions ( T target )
312330 {
313- var properties = typeof ( T ) . GetProperties ( ) ;
331+ var properties = GetCachedProperties ( typeof ( T ) ) ;
314332 var missingOptions = new List < string > ( ) ;
315333
316334 foreach ( var property in properties )
@@ -362,7 +380,7 @@ private Dictionary<string, object> GetEnvironmentVariables()
362380 {
363381 // 获取所有环境变量
364382 var envVars = Environment . GetEnvironmentVariables ( ) ;
365- var properties = typeof ( T ) . GetProperties ( ) ;
383+ var properties = GetCachedProperties ( typeof ( T ) ) ;
366384 var envVarMappings = new Dictionary < string , PropertyInfo > ( StringComparer . OrdinalIgnoreCase ) ;
367385
368386 // 收集环境变量映射
@@ -371,7 +389,7 @@ private Dictionary<string, object> GetEnvironmentVariables()
371389 var envVarAttrs = property . GetCustomAttributes < EnvironmentVariableAttribute > ( ) . ToList ( ) ;
372390 foreach ( var envVarAttr in envVarAttrs )
373391 {
374- if ( envVarAttr != null && ! string . IsNullOrEmpty ( envVarAttr . Name ) )
392+ if ( ! string . IsNullOrEmpty ( envVarAttr . Name ) )
375393 {
376394 envVarMappings [ envVarAttr . Name ] = property ;
377395 }
@@ -409,9 +427,9 @@ private Dictionary<string, object> GetEnvironmentVariables()
409427 }
410428
411429 // 处理布尔值
412- if ( property . PropertyType == typeof ( bool ) && IsBooleanValue ( value ) )
430+ if ( property . PropertyType == typeof ( bool ) && BooleanParser . IsBooleanValue ( value ) )
413431 {
414- result [ property . Name ] = ParseBooleanValue ( value ) ;
432+ result [ property . Name ] = BooleanParser . ParseBooleanValue ( value ) ;
415433 }
416434 else
417435 {
@@ -441,9 +459,9 @@ private Dictionary<string, object> GetEnvironmentVariables()
441459 if ( matchedProperty != null )
442460 {
443461 // 处理布尔值
444- if ( matchedProperty . PropertyType == typeof ( bool ) && IsBooleanValue ( value ) )
462+ if ( matchedProperty . PropertyType == typeof ( bool ) && BooleanParser . IsBooleanValue ( value ) )
445463 {
446- result [ matchedProperty . Name ] = ParseBooleanValue ( value ) ;
464+ result [ matchedProperty . Name ] = BooleanParser . ParseBooleanValue ( value ) ;
447465 }
448466 else
449467 {
@@ -462,38 +480,6 @@ private Dictionary<string, object> GetEnvironmentVariables()
462480 return result ;
463481 }
464482
465- /// <summary>
466- /// 检查字符串值是否为Bool类型
467- /// </summary>
468- /// <param name="value">要检查的字符串值</param>
469- /// <returns>如果是Bool类型值则返回true,否则返回false</returns>
470- private static bool IsBooleanValue ( string value )
471- {
472- if ( string . IsNullOrWhiteSpace ( value ) )
473- {
474- return false ;
475- }
476-
477- var normalizedValue = value . Trim ( ) . ToLowerInvariant ( ) ;
478- return normalizedValue is "true" or "false" or "1" or "0" or "yes" or "no" or "on" or "off" ;
479- }
480-
481- /// <summary>
482- /// 解析Bool类型字符串值
483- /// </summary>
484- /// <param name="value">要解析的字符串值</param>
485- /// <returns>解析后的Bool值</returns>
486- private static bool ParseBooleanValue ( string value )
487- {
488- if ( string . IsNullOrWhiteSpace ( value ) )
489- {
490- return false ;
491- }
492-
493- var normalizedValue = value . Trim ( ) . ToLowerInvariant ( ) ;
494- return normalizedValue is "true" or "1" or "yes" or "on" ;
495- }
496-
497483 /// <summary>
498484 /// 将标准格式参数转换为选项字典
499485 /// </summary>
@@ -564,7 +550,7 @@ private Dictionary<string, object> ConvertToOptionsDictionary(List<string> stand
564550 /// <returns>如果对应布尔属性则返回true,否则返回false</returns>
565551 private bool IsBooleanProperty ( string key )
566552 {
567- var properties = typeof ( T ) . GetProperties ( ) ;
553+ var properties = GetCachedProperties ( typeof ( T ) ) ;
568554 var optionMappings = GetOptionMappings ( ) ;
569555
570556 // 首先尝试通过选项映射查找属性
@@ -590,7 +576,7 @@ private bool IsBooleanProperty(string key)
590576 private Dictionary < string , string > GetOptionMappings ( )
591577 {
592578 var result = new Dictionary < string , string > ( StringComparer . OrdinalIgnoreCase ) ;
593- var properties = typeof ( T ) . GetProperties ( ) ;
579+ var properties = GetCachedProperties ( typeof ( T ) ) ;
594580
595581 foreach ( var property in properties )
596582 {
@@ -649,7 +635,7 @@ private string NormalizeKey(string key)
649635 /// <param name="options">选项字典</param>
650636 private void ApplyOptions ( T target , Dictionary < string , object > options )
651637 {
652- var properties = typeof ( T ) . GetProperties ( )
638+ var properties = GetCachedProperties ( typeof ( T ) )
653639 . Where ( p => p . CanWrite )
654640 . ToList ( ) ;
655641
@@ -686,7 +672,7 @@ private void ApplyOptions(T target, Dictionary<string, object> options)
686672 }
687673
688674 // 获取字符串值
689- string stringValue = kvp . Value . ToString ( ) ;
675+ string stringValue = kvp . Value ? . ToString ( ) ;
690676
691677 // 根据目标类型进行转换
692678 object convertedValue = null ;
@@ -859,15 +845,21 @@ private string NormalizePropertyName(string key)
859845 return string . Empty ;
860846 }
861847
862- key = parts [ 0 ] ;
848+ var sb = new System . Text . StringBuilder ( parts [ 0 ] ) ;
863849
864850 for ( int i = 1 ; i < parts . Length ; i ++ )
865851 {
866- if ( ! string . IsNullOrEmpty ( parts [ i ] ) && parts [ i ] . Length > 0 )
852+ if ( ! string . IsNullOrEmpty ( parts [ i ] ) )
867853 {
868- key += char . ToUpper ( parts [ i ] [ 0 ] ) + ( parts [ i ] . Length > 1 ? parts [ i ] . Substring ( 1 ) : "" ) ;
854+ sb . Append ( char . ToUpperInvariant ( parts [ i ] [ 0 ] ) ) ;
855+ if ( parts [ i ] . Length > 1 )
856+ {
857+ sb . Append ( parts [ i ] . Substring ( 1 ) ) ;
858+ }
869859 }
870860 }
861+
862+ return sb . ToString ( ) ;
871863 }
872864
873865 return key ;
0 commit comments