Skip to content

Commit ea40445

Browse files
authored
feat(ObjectExtensions): add CreateInstanceWithCascade extension method (#5491)
* refactor: 精简代码 * refactor: 使用模式重构代码 * doc: 更新注释文档 * feat: 增加 EnsureInitialized 扩展方法 * feat: 调用 EnsureInitialized 方法 * refactor: 增加扩展方法 * refactor: 兼容属性为类时未初始化问题 * refactor: 代码重构 * refactor: 更新代码 * chore: bump version 9.4.3-beta04 * refactor: 更正单词拼写
1 parent 16eabff commit ea40445

File tree

3 files changed

+46
-8
lines changed

3 files changed

+46
-8
lines changed

src/BootstrapBlazor/BootstrapBlazor.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk.Razor">
22

33
<PropertyGroup>
4-
<Version>9.4.3-beta03</Version>
4+
<Version>9.4.3-beta04</Version>
55
</PropertyGroup>
66

77
<ItemGroup>

src/BootstrapBlazor/Components/Table/Table.razor.Edit.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -300,11 +300,11 @@ private TItem CreateInstance()
300300
{
301301
try
302302
{
303-
return Activator.CreateInstance<TItem>();
303+
return ObjectExtensions.CreateInstanceWithCascade<TItem>();
304304
}
305-
catch (Exception)
305+
catch (Exception ex)
306306
{
307-
throw new InvalidOperationException($"{typeof(TItem)} missing new() method. Please provider {nameof(CreateItemCallback)} create the {typeof(TItem)} instance. {typeof(TItem)} 未提供无参构造函数 new() 请通过 {nameof(CreateItemCallback)} 回调方法创建实例");
307+
throw new InvalidOperationException($"{typeof(TItem)} missing new() method. Please provide {nameof(CreateItemCallback)} create the {typeof(TItem)} instance. {typeof(TItem)} 未提供无参构造函数 new() 请通过 {nameof(CreateItemCallback)} 回调方法创建实例", ex);
308308
}
309309
}
310310

src/BootstrapBlazor/Extensions/ObjectExtensions.cs

+42-4
Original file line numberDiff line numberDiff line change
@@ -137,14 +137,14 @@ public static string GetTypeDesc(this Type t)
137137
/// 字符串类型转换为其他数据类型
138138
/// </summary>
139139
/// <returns></returns>
140-
public static bool TryConvertTo(this string? source, Type type, [MaybeNullWhen(false)] out object? val)
140+
public static bool TryConvertTo(this string? source, Type type, out object? val)
141141
{
142142
var ret = true;
143143
val = source;
144144
if (type != typeof(string))
145145
{
146146
ret = false;
147-
var methodInfo = Array.Find(typeof(ObjectExtensions).GetMethods(), m => m.Name == nameof(TryConvertTo) && m.IsGenericMethod);
147+
var methodInfo = Array.Find(typeof(ObjectExtensions).GetMethods(), m => m is { Name: nameof(TryConvertTo), IsGenericMethod: true });
148148
if (methodInfo != null)
149149
{
150150
methodInfo = methodInfo.MakeGenericMethod(type);
@@ -159,7 +159,7 @@ public static bool TryConvertTo(this string? source, Type type, [MaybeNullWhen(f
159159
}
160160

161161
/// <summary>
162-
///
162+
/// Tries to convert the string representation of a value to a specified type.
163163
/// </summary>
164164
/// <typeparam name="TValue"></typeparam>
165165
/// <param name="source"></param>
@@ -203,7 +203,7 @@ public static bool TryConvertTo<TValue>(this string? source, [MaybeNullWhen(fals
203203
}
204204

205205
/// <summary>
206-
/// 格式化为 文件大小与单位格式 字符串
206+
/// Formats the file size into a string with appropriate units
207207
/// </summary>
208208
/// <param name="fileSize"></param>
209209
/// <returns></returns>
@@ -237,4 +237,42 @@ internal static void Clone<TModel>(this TModel source, TModel item)
237237
}
238238
}
239239
}
240+
241+
/// <summary>
242+
/// Creates an instance of a type and ensures all class-type properties are initialized.
243+
/// </summary>
244+
/// <typeparam name="TItem">The type to create an instance of.</typeparam>
245+
/// <returns>An instance of the specified type with initialized properties.</returns>
246+
public static TItem CreateInstanceWithCascade<TItem>()
247+
{
248+
var instance = Activator.CreateInstance<TItem>();
249+
instance!.EnsureInitialized();
250+
return instance;
251+
}
252+
253+
/// <summary>
254+
/// Ensures that all class-type properties of the instance are initialized.
255+
/// </summary>
256+
/// <param name="instance">The instance to initialize properties for.</param>
257+
private static void EnsureInitialized(this object instance)
258+
{
259+
// Reflection performance needs to be optimized here
260+
foreach (var propertyInfo in instance.GetType().GetProperties().Where(p => p.PropertyType.IsClass && p.PropertyType != typeof(string)))
261+
{
262+
var type = propertyInfo.PropertyType;
263+
var value = propertyInfo.GetValue(instance, null);
264+
if (value is null)
265+
{
266+
var pv = CreateInstance(type);
267+
propertyInfo.SetValue(instance, pv);
268+
}
269+
}
270+
}
271+
272+
private static object? CreateInstance(Type type)
273+
{
274+
var instance = Activator.CreateInstance(type);
275+
instance!.EnsureInitialized();
276+
return instance;
277+
}
240278
}

0 commit comments

Comments
 (0)