遍历FHIR能力声明时,如何访问Binding中ValueSet的属性?
问题场景
我正在遍历FHIR能力声明及对应的结构定义,目标是提取服务器支持的所有问题和值集列表。遍历结构定义的快照元素时,发现部分元素包含binding字段,调试断点和控制台能看到element.Binding.ValueSet已正确填充值集信息,但代码中无法直接访问它的属性。
调试时的对象信息
即时窗口显示element.Binding.ValueSet的详细内容:
element.Binding.ValueSet
{url: http://hl7.org/fhir/ValueSet/adverse-event-category}
Children: {Hl7.Fhir.Model.ResourceReference.<get_Children>d__32}
Display: null
DisplayElement: null
ElementId: null
Extension: Count = 0
Identifier: null
IsContainedReference: false
NamedChildren: {Hl7.Fhir.Model.ResourceReference.<get_NamedChildren>d__34}
Reference: "http://hl7.org/fhir/ValueSet/adverse-event-category"
ReferenceElement: {Value="http://hl7.org/fhir/ValueSet/adverse-event-category"}
Type: null
TypeElement: null
TypeName: "Reference"
Url: {http://hl7.org/fhir/ValueSet/adverse-event-category}
Results View: Expanding the Results View will enumerate the IEnumerable
遇到的错误
尝试调用element.Binding.ValueSet.Reference获取值集URL时,编译器报错:
element.Binding.ValueSet.Reference
error CS1061: 'DataType' does not contain a definition for 'Reference' and no accessible extension method 'Reference' accepting a first argument of type 'DataType' could be found (are you missing a using directive or an assembly reference?)
类型与属性查询结果
查询对象运行时类型:
element.Binding.ValueSet.GetType()(结果节选)
{Name = "ResourceReference" FullName = "Hl7.Fhir.Model.ResourceReference"}
Assembly: {Hl7.Fhir.Support.Poco, Version=4.3.0.0, Culture=neutral, PublicKeyToken=d706911480550fc3}
BaseType: {Name = "DataType" FullName = "Hl7.Fhir.Model.DataType"}
FullName: "Hl7.Fhir.Model.ResourceReference"
Namespace: "Hl7.Fhir.Model"
查询对象的可用属性:
element.Binding.ValueSet.GetType().GetProperties()
{System.Reflection.PropertyInfo[14]}
[0]: {System.String TypeName}
[1]: {Hl7.Fhir.Model.FhirString ReferenceElement}
[2]: {System.String Reference}
[3]: {Hl7.Fhir.Model.FhirUri TypeElement}
[4]: {System.String Type}
[5]: {Hl7.Fhir.Model.Identifier Identifier}
[6]: {Hl7.Fhir.Model.FhirString DisplayElement}
[7]: {System.String Display}
[8]: {System.Collections.Generic.IEnumerable'1[Hl7.Fhir.Model.Base] Children}
[9]: {System.Collections.Generic.IEnumerable'1[Hl7.Fhir.Model.ElementValue] NamedChildren}
[10]: {System.Uri Url}
[11]: {Boolean IsContainedReference}
[12]: {System.String ElementId}
[13]: {System.Collections.Generic.List`1[Hl7.Fhir.Model.Extension] Extension}
将对象转为列表后的结果:
element.Binding.ValueSet.ToList()
Count = 1
[0]: {[reference, {Value=http://hl7.org/fhir/ValueSet/adverse-event-category}]}
但调用element.Binding.ValueSet.Keys或element.Binding.ValueSet.Values均无法正常工作。
解决方案
问题核心是:element.Binding.ValueSet的编译时类型是DataType,但运行时实际是ResourceReference子类,编译器只识别父类的成员,因此需要先做类型转换再访问子类属性。
方法1:强制类型转换+空值判断
var valueSetRef = element.Binding.ValueSet as Hl7.Fhir.Model.ResourceReference; if (valueSetRef != null) { // 获取值集URL的两种方式 string valueSetUrl = valueSetRef.Reference; Uri valueSetUri = valueSetRef.Url; }
方法2:模式匹配(C# 7.0及以上版本)
if (element.Binding.ValueSet is Hl7.Fhir.Model.ResourceReference valueSetRef) { string valueSetUrl = valueSetRef.Reference; Uri valueSetUri = valueSetRef.Url; }
补充说明
- 调试时能看到属性是因为调试器直接读取运行时对象的成员,而编译阶段编译器仅基于声明类型(
DataType)做检查。 - 如果存在非
ResourceReference类型的ValueSet绑定场景,建议先判断类型再处理,避免转换失败抛出异常。
内容的提问来源于stack exchange,提问作者Mark Cooper

