用扩展方法替换字符串值
Replace string value with extension method
所以我主要做的是解析消息(HL7 标准)。
有时这些 HL7 消息包含一条 "whole" 记录,包含所有信息,有时其中只有更新的部分。
这是一行数据的示例。假设这一行包含一些 patient/client 信息,如姓名、出生日期等。它可能看起来像这样:
|Mike|Miller|19790530|truck driver|blonde|m|
列实际上代表了这个:
|first name|surname|date of birth|job|hair color|gender|
现在这是一整行数据。
更新可能是这样的(他结婚了,失业了,换了头发颜色):
||O'Connor||""|brown||
其中""
代表job栏的数值,brown
代表头发颜色的变化
在 HL7 标准中规定,省略字段(例如名字或性别)表示未进行任何更改,而 ""
表示该字段中的数据已被删除.具有值的字段可能需要更新。所以我的名字更新逻辑看起来与此类似(pidEntity
是一个数据库对象,不是先创建代码,而是先创建数据库,pidEntity.FirstName
是一个 属性)
var pid = this.message.PID; // patient identification object from parsed message
if (pid.PatientName.GivenName.Value == string.Empty)
{
// "" => deletion flag
pidEntity.FirstName = null;
}
else if (pid.PatientName.GivenName.Value == null)
{
// omitted, no changes
return;
}
pidEntity.FirstName = pid.PatientName.GivenName.Value;
我做了很多这样的字符串更新,所以我想嘿 - 为什么不尝试使用扩展方法或带有 ref
参数的方法。
我的第一次尝试是这样的:
// doesn't work because strings are immutable
public static void Update(this string @this, string newValue)
{
if (newValue == string.Empty) @this = null;
else if (newValue == null) return;
@this = newValue;
}
// usage
pidEntity.FirstName.Update(pid.PatientName.GivenName.Value);
把第一个参数改成this ref string @this
也不行。使用 out
或 ref
的更新函数也不行,因为不能像这样将属性作为 ref 或 out 参数传递:
public static void Update(ref string property, string newValue)
// usage
Update(pidEntity.FirstName, pid.PatientName.GivenName.Value);
到目前为止我能想到的最多 "elegant" 是这样的,忽略了 ""
意味着将数据库对象的值设置为 null
并将其设置为空的事实改为字符串。
pidEntity.FirstName = pid.PatientName.GivenName.Value ?? pidEntity.FirstName;
我的另一个解决方案是像这样工作的扩展方法:
public static void UpdateString(this string hl7Value, Action<string> updateAct)
{
if (updateAct == null) throw new ArgumentNullException(nameof(updateAct));
if (hl7Value == string.Empty) updateAct(null);
else if (hl7Value == null) return;
updateAct(hl7Value);
}
// usage
pid.PatientName.GivenName.Value.UpdateString(v => pidEntity.FirstName = v);
我认为一定有更简单的方法,但我需要你的帮助(也许是 Reflection?):)
字符串是 immutable - 您可以创建新字符串,但不能更新字符串的现有实例。
所以我主要做的是解析消息(HL7 标准)。
有时这些 HL7 消息包含一条 "whole" 记录,包含所有信息,有时其中只有更新的部分。
这是一行数据的示例。假设这一行包含一些 patient/client 信息,如姓名、出生日期等。它可能看起来像这样:
|Mike|Miller|19790530|truck driver|blonde|m|
列实际上代表了这个:
|first name|surname|date of birth|job|hair color|gender|
现在这是一整行数据。
更新可能是这样的(他结婚了,失业了,换了头发颜色):
||O'Connor||""|brown||
其中""
代表job栏的数值,brown
代表头发颜色的变化
在 HL7 标准中规定,省略字段(例如名字或性别)表示未进行任何更改,而 ""
表示该字段中的数据已被删除.具有值的字段可能需要更新。所以我的名字更新逻辑看起来与此类似(pidEntity
是一个数据库对象,不是先创建代码,而是先创建数据库,pidEntity.FirstName
是一个 属性)
var pid = this.message.PID; // patient identification object from parsed message
if (pid.PatientName.GivenName.Value == string.Empty)
{
// "" => deletion flag
pidEntity.FirstName = null;
}
else if (pid.PatientName.GivenName.Value == null)
{
// omitted, no changes
return;
}
pidEntity.FirstName = pid.PatientName.GivenName.Value;
我做了很多这样的字符串更新,所以我想嘿 - 为什么不尝试使用扩展方法或带有 ref
参数的方法。
我的第一次尝试是这样的:
// doesn't work because strings are immutable
public static void Update(this string @this, string newValue)
{
if (newValue == string.Empty) @this = null;
else if (newValue == null) return;
@this = newValue;
}
// usage
pidEntity.FirstName.Update(pid.PatientName.GivenName.Value);
把第一个参数改成this ref string @this
也不行。使用 out
或 ref
的更新函数也不行,因为不能像这样将属性作为 ref 或 out 参数传递:
public static void Update(ref string property, string newValue)
// usage
Update(pidEntity.FirstName, pid.PatientName.GivenName.Value);
到目前为止我能想到的最多 "elegant" 是这样的,忽略了 ""
意味着将数据库对象的值设置为 null
并将其设置为空的事实改为字符串。
pidEntity.FirstName = pid.PatientName.GivenName.Value ?? pidEntity.FirstName;
我的另一个解决方案是像这样工作的扩展方法:
public static void UpdateString(this string hl7Value, Action<string> updateAct)
{
if (updateAct == null) throw new ArgumentNullException(nameof(updateAct));
if (hl7Value == string.Empty) updateAct(null);
else if (hl7Value == null) return;
updateAct(hl7Value);
}
// usage
pid.PatientName.GivenName.Value.UpdateString(v => pidEntity.FirstName = v);
我认为一定有更简单的方法,但我需要你的帮助(也许是 Reflection?):)
字符串是 immutable - 您可以创建新字符串,但不能更新字符串的现有实例。