diff --git a/src/BootstrapBlazor/BootstrapBlazor.csproj b/src/BootstrapBlazor/BootstrapBlazor.csproj index 91eaeb1b231..bf5f5cb5aca 100644 --- a/src/BootstrapBlazor/BootstrapBlazor.csproj +++ b/src/BootstrapBlazor/BootstrapBlazor.csproj @@ -1,7 +1,7 @@ - 9.4.3-beta03 + 9.4.3-beta04 diff --git a/src/BootstrapBlazor/Components/Table/Table.razor.Edit.cs b/src/BootstrapBlazor/Components/Table/Table.razor.Edit.cs index 853f873ccaf..33343ab736b 100644 --- a/src/BootstrapBlazor/Components/Table/Table.razor.Edit.cs +++ b/src/BootstrapBlazor/Components/Table/Table.razor.Edit.cs @@ -300,11 +300,11 @@ private TItem CreateInstance() { try { - return Activator.CreateInstance(); + return ObjectExtensions.CreateInstanceWithCascade(); } - catch (Exception) + catch (Exception ex) { - throw new InvalidOperationException($"{typeof(TItem)} missing new() method. Please provider {nameof(CreateItemCallback)} create the {typeof(TItem)} instance. {typeof(TItem)} 未提供无参构造函数 new() 请通过 {nameof(CreateItemCallback)} 回调方法创建实例"); + throw new InvalidOperationException($"{typeof(TItem)} missing new() method. Please provide {nameof(CreateItemCallback)} create the {typeof(TItem)} instance. {typeof(TItem)} 未提供无参构造函数 new() 请通过 {nameof(CreateItemCallback)} 回调方法创建实例", ex); } } diff --git a/src/BootstrapBlazor/Extensions/ObjectExtensions.cs b/src/BootstrapBlazor/Extensions/ObjectExtensions.cs index d86bc9e4762..637e0db9f6a 100644 --- a/src/BootstrapBlazor/Extensions/ObjectExtensions.cs +++ b/src/BootstrapBlazor/Extensions/ObjectExtensions.cs @@ -137,14 +137,14 @@ public static string GetTypeDesc(this Type t) /// 字符串类型转换为其他数据类型 /// /// - public static bool TryConvertTo(this string? source, Type type, [MaybeNullWhen(false)] out object? val) + public static bool TryConvertTo(this string? source, Type type, out object? val) { var ret = true; val = source; if (type != typeof(string)) { ret = false; - var methodInfo = Array.Find(typeof(ObjectExtensions).GetMethods(), m => m.Name == nameof(TryConvertTo) && m.IsGenericMethod); + var methodInfo = Array.Find(typeof(ObjectExtensions).GetMethods(), m => m is { Name: nameof(TryConvertTo), IsGenericMethod: true }); if (methodInfo != null) { methodInfo = methodInfo.MakeGenericMethod(type); @@ -159,7 +159,7 @@ public static bool TryConvertTo(this string? source, Type type, [MaybeNullWhen(f } /// - /// + /// Tries to convert the string representation of a value to a specified type. /// /// /// @@ -203,7 +203,7 @@ public static bool TryConvertTo(this string? source, [MaybeNullWhen(fals } /// - /// 格式化为 文件大小与单位格式 字符串 + /// Formats the file size into a string with appropriate units /// /// /// @@ -237,4 +237,42 @@ internal static void Clone(this TModel source, TModel item) } } } + + /// + /// Creates an instance of a type and ensures all class-type properties are initialized. + /// + /// The type to create an instance of. + /// An instance of the specified type with initialized properties. + public static TItem CreateInstanceWithCascade() + { + var instance = Activator.CreateInstance(); + instance!.EnsureInitialized(); + return instance; + } + + /// + /// Ensures that all class-type properties of the instance are initialized. + /// + /// The instance to initialize properties for. + private static void EnsureInitialized(this object instance) + { + // Reflection performance needs to be optimized here + foreach (var propertyInfo in instance.GetType().GetProperties().Where(p => p.PropertyType.IsClass && p.PropertyType != typeof(string))) + { + var type = propertyInfo.PropertyType; + var value = propertyInfo.GetValue(instance, null); + if (value is null) + { + var pv = CreateInstance(type); + propertyInfo.SetValue(instance, pv); + } + } + } + + private static object? CreateInstance(Type type) + { + var instance = Activator.CreateInstance(type); + instance!.EnsureInitialized(); + return instance; + } }