C#中ExpandoObject扩展对象如何实现Optional Chaining可选链操作?
ExpandoObject 安全访问属性解决方案
C# 原生可选链 ?. 不支持动态类型的成员访问,因此无法直接对 ExpandoObject 的动态属性使用可选链操作。但ExpandoObject本身实现了IDictionary<string, object>接口,你可以通过以下几种方式实现和可选链等价的安全访问效果:
方案1:直接通过字典接口访问
直接将ExpandoObject强转为字典,使用TryGetValue判断属性是否存在,Razor 中写法如下:
<div>Creation date:</div> <div>@(((IDictionary<string, object>)Model.DynamicData).TryGetValue("CreationDate", out var date) ? date : "未设置")</div>
方案2:封装扩展方法简化调用
可以编写通用扩展方法,一劳永逸简化后续调用:
public static class ExpandoObjectExtensions { public static T? GetValueOrDefault<T>(this ExpandoObject? expando, string propertyName, T? defaultValue = default) { if (expando == null) return defaultValue; IDictionary<string, object> dict = expando; if (dict.TryGetValue(propertyName, out var value) && value is T typedValue) { return typedValue; } return defaultValue; } }
封装后Razor中的调用非常简洁,支持后续链式调用其他方法:
<div>Creation date:</div> <div>@Model.DynamicData.GetValueOrDefault<DateTime?>("CreationDate")?.ToString("yyyy-MM-dd") ?? "无创建日期"</div>
注意:如果
DynamicData本身可能为null,可以在调用扩展方法前加可选链:@Model.DynamicData?.GetValueOrDefault<DateTime?>("CreationDate")
内容的提问来源于stack exchange,提问作者Ali EXE
相关产品推荐
相关产品推荐

