c# - 如何在运行时修改“DataMember”属性的“Order”?
问题描述
我有一个数据成员,其中提到了订单值。我想根据选择查询中存在的参数顺序修改值。我无法在运行时设置数据成员的顺序值。
下面是我试过的代码:
[DataContract]
public class Details
{
[DataMember(EmitDefaultValue = false, Order = 1)]
public string id;
[DataMember(EmitDefaultValue = false, Order = 1)]
public string name;
[DataMember(EmitDefaultValue = false, Order = 1)]
public string creator;
[DataMember(EmitDefaultValue = false, Order = 1)]
public string format;
[DataMember(EmitDefaultValue = false, Order = 1)]
public string creationTime;
}
Type type = executing.GetType("Details");
FieldInfo[] properties = type.GetFields();
properties[0].GetCustomAttributes(typeof(DataMemberAttribute), true).SetValue(2, 3);
我尝试了上面的代码来获取自定义属性和设置值,但它不起作用。是否可以在运行时更改属性值?
解决方案
不幸的是,没有办法Order
在运行时更改参数的值。属性已在构建时评估并集成到编译代码中,因此您只能提供常量值。
最通用的方法是更改序列化代码,以便按请求的顺序对属性进行序列化,但这对于调整顺序来说太费力和风险了,至少恕我直言。
但是,如果您有一组非常有限的可能查询来为每个变体创建单独的方法,并且返回值具有根据需要调整值的不同类,那么您可以做什么。一种可能的方法是为所有对象创建一个基类。首先,您必须在基类中使用属性而不是字段。此外,关键字virtual
为在派生类中被覆盖的属性做准备:
[DataContract]
public class Details
{
[DataMember(EmitDefaultValue = false, Order = 1)]
public virtual string id { get; set; }
[DataMember(EmitDefaultValue = false, Order = 1)]
public virtual string name { get; set; }
[DataMember(EmitDefaultValue = false, Order = 1)]
public virtual string creator { get; set; }
[DataMember(EmitDefaultValue = false, Order = 1)]
public virtual string format { get; set; }
[DataMember(EmitDefaultValue = false, Order = 1)]
public virtual string creationTime { get; set; }
}
对于每个变体,您将创建一个派生类,例如:
[DataContract]
public class DetailsVariantA : Details
{
[DataMember(EmitDefaultValue = false, Order = 5)]
public override string id { get; set; }
[DataMember(EmitDefaultValue = false, Order = 4)]
public override string name { get; set; }
[DataMember(EmitDefaultValue = false, Order = 3)]
public override string creator { get; set; }
[DataMember(EmitDefaultValue = false, Order = 2)]
public override string format { get; set; }
[DataMember(EmitDefaultValue = false, Order = 1)]
public override string creationTime { get; set; }
}
变体 A 的方法将返回一个类型的对象,DetailsVariantA
而不是Details
.
请注意:正如您在示例中看到的那样,这种方法还涉及大量额外代码,因为每个变体都有另一个类。此外,它还引入了以后有人忘记将属性添加到所有派生类等的风险。
由于 WCF 主要用于在机器之间交换数据,并且数据通常不会被人类读取,因此从我的角度来看,我不会投入精力并引入这种仅更改顺序的风险。
推荐阅读
- javascript - Symfony FOSCKE onchange 事件
- java - Spring Batch Scheduler:定时器实现
- reactjs - React 待办事项列表,从未完成列表移至已完成列表,并在同一 li 上提供信息
- php - ImageMagick 透视变形画阴影,如何防止
- laravel - 无法为从我的 Bitbucket 存储库克隆的 Laravel 项目提供服务
- google-analytics - 实时报告中未显示 Google Measurement Protocol Timing 匹配类型
- python - 如果调用 requests.get() 则处理
- python - 运行 UPDATE (oracle) ,从数据框列完成序列
- c - Polyspace 未转发声明 main() 的警报
- angular - Watson语音到文本角度