C# 在C中查找两个对象之间的差异#
我正在寻找一种方法来获得一个对象的两个实例之间的差异。C# 在C中查找两个对象之间的差异#,c#,.net,system.reflection,variance,C#,.net,System.reflection,Variance,我正在寻找一种方法来获得一个对象的两个实例之间的差异。 我编写的以下函数使用反射来实现当前的目的,但我希望对其进行更多的增强,以便它可以跳过带有特定数据注释的某些字段。例如,在实体框架模型中使用的“[NotMapped]”和[JsonIgnore]”注释 public static List<ChangeSet> GetVariances<T>(this T previous, T updated) { List<ChangeSet&
我编写的以下函数使用反射来实现当前的目的,但我希望对其进行更多的增强,以便它可以跳过带有特定数据注释的某些字段。例如,在实体框架模型中使用的“[NotMapped]”和[JsonIgnore]”注释
public static List<ChangeSet> GetVariances<T>(this T previous, T updated)
{
List<ChangeSet> changeSet = new List<ChangeSet>();
try
{
string[] excludedFields = { "Id", "DateCreated", "DateModified" };
Type entityType = previous.GetType();
FieldInfo[] fieldInfo = entityType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
foreach (FieldInfo x in fieldInfo)
{
if (!excludedFields.Any(z => x.Name.Contains(z))){
ChangeSet change = new ChangeSet
{
Field = x.Name,
PreviousValue = x.GetValue(previous),
UpdatedValue = x.GetValue(updated)
};
if (!Equals(change.PreviousValue, change.UpdatedValue))
changeSet.Add(change);
}
}
}
catch (Exception ex)
{
var exception = ex.Message;
}
return changeSet;
}
public static List GetVariances(此T先前,T更新)
{
列表变更集=新列表();
尝试
{
字符串[]excludedFields={“Id”、“DateCreated”、“DateModified”};
类型entityType=previous.GetType();
FieldInfo[]FieldInfo=entityType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
foreach(FieldInfo中的FieldInfo x)
{
如果(!excludedFields.Any(z=>x.Name.Contains(z))){
变更集变更=新变更集
{
字段=x.名称,
PreviousValue=x.GetValue(上一个),
UpdatedValue=x.GetValue(已更新)
};
如果(!等于(change.PreviousValue,change.UpdatedValue))
变更集。添加(变更);
}
}
}
捕获(例外情况除外)
{
var异常=例如消息;
}
返回变更集;
}
正在使用的模型示例:
[Table("ClientMaster")]
public partial class ClientMaster
{
[Key]
[JsonProperty(PropertyName = "id")]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
[JsonProperty(PropertyName = "clientId")]
[Required, StringLength(250)]
public string ClientId { get; set; }
[JsonProperty(PropertyName = "approvalLevel")]
[Required, StringLength(200)]
public string ApprovalLevel { get; set; }
[NotMapped]
[JsonProperty(PropertyName = "attachments")]
public List<ClientAttachmentModel> Attachments { get; set; }
[JsonIgnore]
public virtual UserInformation CreatedByUser { get; set; }
[JsonIgnore]
public virtual UserInformation ModifiedByUser { get; set; }
[JsonIgnore]
public virtual ICollection<TaskMaster> TaskMaster { get; set; }
}
[表(“客户端主机”)]
公共部分类ClientMaster
{
[关键]
[JsonProperty(PropertyName=“id”)]
[数据库生成(DatabaseGeneratedOption.Identity)]
公共长Id{get;set;}
[JsonProperty(PropertyName=“clientId”)]
[所需长度(250)]
公共字符串ClientId{get;set;}
[JsonProperty(PropertyName=“approvalLevel”)]
[所需长度(200)]
公共字符串ApprovalLevel{get;set;}
[未映射]
[JsonProperty(PropertyName=“附件”)]
公共列表附件{get;set;}
[JsonIgnore]
公共虚拟用户信息CreatedByUser{get;set;}
[JsonIgnore]
公共虚拟用户信息ModifiedByUser{get;set;}
[JsonIgnore]
公共虚拟ICollection任务主管{get;set;}
}
谁能指导我让函数跳过某些数据注释。
非常感谢您的帮助。您可以使用
attribute.IsDefined
var hasAttribute = Attribute.IsDefined(x, typeof(NotMappedAttribute));
如果您要查找的只是装饰特定属性的属性,则需要对类型调用
GetProperties
,而不是像当前那样调用GetFields
。这是因为属性是装饰属性,而不是字段GetFields
将检索编译器生成的支持字段,这可能不是您想要的。您仍然可以以相同的方式执行值比较
现在,为了检查属性,由GetProperties
返回的数组中的每个PropertyInfo
对象将有一个数组属性CustomAttributes
,其中包含该属性的装饰属性的详细信息以及您为这些属性提供的任何参数。如果您只想检查属性的存在,而不关心参数,那么Magnus的解决方案可以实现同样的效果,而且速度更快
(我还要提到,在您的代码示例中,使用
Name.Contains
将意味着,例如,ClientId
将被跳过,因为它的名称包含Id
,您将其列为排除字段。Name
对于您声明的属性,只需返回声明的名称,这样您就可以检查是否相等。)y、 )我对您的实际问题感到好奇…但我想进一步增强它,这样它就可以跳过带有特定数据批注的特定字段
…所以您在中发布了一个问题以便提问…“跳过带有特定数据批注的特定字段”这是您的问题吗?然后搜索“如何获取在c#”或类似语言中具有自定义属性的成员。@Patrickhoffman我希望跳过数据批注,如“[未映射]“,我应该以何种方式修改代码以实现此目的。感谢您的及时响应。我将进行这些更改并进行尝试。PropertyInfo工作正常,很抱歉我与MemberInfo混淆了。我删除了名称。如您所述,Contains非常有效。再次感谢!没问题,很高兴能提供帮助!”!