WAQ*_*WAQ 2 c# asp.net comparison
在我的 Web 应用程序中,我想在某些内容通过 UI 发生更改时通知用户。例如我的项目类看起来像这样
public class Project
{
public string Name { get; set; }
public TaskStatus Status { get; set; }
public string Planner { get; set; }
public DateTime ScheduleStart { get; set; }
public DateTime ScheduleEnd { get; set; }
public double EstimatedCost { get; set; }
public double ActualCost { get; set; }
public string AssignedTo { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
现在,我已将此信息显示在 UI 上,并且有权更改某些内容(例如状态、计划、成本等)的特定用户可以更改此信息。所以我想要的是,当用户更改某些内容时,应该发送电子邮件以通知项目经理或任何感兴趣的人。
我编写了所有其他所需的代码来发送电子邮件和管理权限等。现在我想具体了解哪些内容发生了变化,例如如果只有 Planner 发生了变化,或者状态发生了变化,那么电子邮件应该包含新值和旧值,就像 TFS 生成通知一样。
PS:上面的代码显示了我的 Project 类的一个非常简单的版本,实际的类有 30 多个属性。所以我在想,不应该对每个单独的属性进行比较,而应该有一种更简单和通用的方法来告诉我哪些属性发生了变化,以便我可以根据它们进行通知。
基于反射的简单解决方案。请注意,它可以进行优化,并且它不支持(目前)比较内部集合/对象。比较对象必须是POD(Plain Old Data)
public class Project
{
public string Name { get; set; }
public TaskStatus Status { get; set; }
public string Planner { get; set; }
public DateTime ScheduleStart { get; set; }
public DateTime ScheduleEnd { get; set; }
public double EstimatedCost { get; set; }
public double ActualCost { get; set; }
public string AssignedTo { get; set; }
public Project Clone()
{
// If your object has inner collections, or
// references to other objects, you'll have to deep
// clone them ***manually***!!!
return (Project)MemberwiseClone();
}
}
public static class SimpleComparer
{
// Item1: property name, Item2 current, Item3 original
public static List<Tuple<string, object, object>> Differences<T>(T current, T original)
{
var diffs = new List<Tuple<string, object, object>>();
MethodInfo areEqualMethod = typeof(SimpleComparer).GetMethod("AreEqual", BindingFlags.Static | BindingFlags.NonPublic);
foreach (PropertyInfo prop in typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public))
{
object x = prop.GetValue(current);
object y = prop.GetValue(original);
bool areEqual = (bool)areEqualMethod.MakeGenericMethod(prop.PropertyType).Invoke(null, new object[] { x, y });
if (!areEqual)
{
diffs.Add(Tuple.Create(prop.Name, x, y));
}
}
return diffs;
}
private static bool AreEqual<T>(T x, T y)
{
return EqualityComparer<T>.Default.Equals(x, y);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您需要一个Clone()方法:
public class Project
{
public string Name { get; set; }
public TaskStatus Status { get; set; }
public string Planner { get; set; }
public DateTime ScheduleStart { get; set; }
public DateTime ScheduleEnd { get; set; }
public double EstimatedCost { get; set; }
public double ActualCost { get; set; }
public string AssignedTo { get; set; }
public Project Clone()
{
// If your object has inner collections, you'll have to deep
// clone them ***manually***!!!
return (Project)MemberwiseClone();
}
}
Run Code Online (Sandbox Code Playgroud)
进而...
var current = new Project();
var original = current.Clone();
current.ActualCost = 10000;
var diffs = SimpleComparer.Differences(current, original);
foreach (var diff in diffs)
{
Console.WriteLine("'{0}' changed from {1} to {2}", diff.Item1, diff.Item3, diff.Item2);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3343 次 |
| 最近记录: |