我有一个代码块,将类型序列化为Html标记.
Type t = typeof(T); // I pass <T> in as a paramter, where myObj is of type T
tagBuilder.Attributes.Add("class", t.Name);
foreach (PropertyInfo prop in t.GetProperties())
{
object propValue = prop.GetValue(myObj, null);
string stringValue = propValue != null ? propValue.ToString() : String.Empty;
tagBuilder.Attributes.Add(prop.Name, stringValue);
}
Run Code Online (Sandbox Code Playgroud)
这个伟大的工程,但我希望它只是对基本类型,像这样做int,double,bool等,以及其他类型的不是原始的,但可以很容易地连载一样string.我希望它忽略列表和其他自定义类型之类的所有内容.
任何人都可以建议我这样做吗?或者我是否需要指定我想要允许的类型并打开属性的类型以查看是否允许它?这有点乱,所以如果我有一个更整洁的方式会很好.
我正在处理的项目需要一些简单的审计日志记录,以便用户更改其电子邮件,帐单地址等.我们正在使用的对象来自不同的来源,一个是WCF服务,另一个是Web服务.
我已经使用反射实现了以下方法来查找对两个不同对象的属性的更改.这将生成一个属性列表,这些属性与旧值和新值有差异.
public static IList GenerateAuditLogMessages(T originalObject, T changedObject)
{
IList list = new List();
string className = string.Concat("[", originalObject.GetType().Name, "] ");
foreach (PropertyInfo property in originalObject.GetType().GetProperties())
{
Type comparable =
property.PropertyType.GetInterface("System.IComparable");
if (comparable != null)
{
string originalPropertyValue =
property.GetValue(originalObject, null) as string;
string newPropertyValue =
property.GetValue(changedObject, null) as string;
if (originalPropertyValue != newPropertyValue)
{
list.Add(string.Concat(className, property.Name,
" changed from '", originalPropertyValue,
"' to '", newPropertyValue, "'"));
}
}
}
return list;
}Run Code Online (Sandbox Code Playgroud)
我正在寻找System.IComparable,因为"所有数字类型(如Int32和Double)都实现IComparable,String,Char和DateTime也是如此." 这似乎是找到任何不是自定义类的属性的最佳方法.
利用由WCF或Web服务代理代码生成的PropertyChanged事件听起来不错,但没有为我的审计日志(旧值和新值)提供足够的信息.
如果有更好的方法来寻找输入,谢谢!
@Aaronaught,这里是一些基于执行object.Equals生成正匹配的示例代码:
Address …Run Code Online (Sandbox Code Playgroud) 我有以下方法:
protected override bool ModifyExistingEntity(Product entity, ProductModel item)
{
bool isModified = false;
if (entity.Title != item.Title)
{
isModified = true;
entity.Title = item.Title;
}
if (entity.ServerId != item.Id)
{
isModified = true;
entity.ServerId = item.Id;
}
return isModified;
}
Run Code Online (Sandbox Code Playgroud)
我想知道你是否可以建议一种更好的方法来实现该方法.
问题很明显:每个属性有5行几乎复制粘贴的代码太多了.可能是我的愿景中使用Func-s/Expression-s 的解决方案.
我最近遇到过这种情况,到目前为止,我一直在愉快地重写等于运算符(==)和/或Equals方法,以查看两个引用类型是否实际包含相同的数据(即两个看起来相同的不同实例).
我一直在使用它,因为我已经进行了更多的自动化测试(比较参考/预期数据与返回的数据).
在查看MSDN中的一些编码标准指南时,我遇到了一篇建议反对它的文章.现在我理解为什么文章说这个(因为它们不是同一个实例)但它没有回答这个问题:
非常感谢^ _ ^
看起来我错误地阅读了一些文档(这是漫长的一天)并且压倒Equals可能是要走的路.
如果要实现引用类型,则应考虑在引用类型上覆盖Equals方法(如果类型看起来像基本类型,如Point,String,BigNumber等).大多数引用类型不应重载等于运算符,即使它们重写等于.但是,如果要实现旨在具有值语义的引用类型(例如复数类型),则应覆盖相等运算符.
我有这些数据传输对象:
public class Report
{
public int Id { get; set; }
public int ProjectId { get; set; }
//and so on for many, many properties.
}
Run Code Online (Sandbox Code Playgroud)
我不想写
public bool areEqual(Report a, Report b)
{
if (a.Id != b.Id) return false;
if (a.ProjectId != b.ProjectId) return false;
//Repeat ad nauseum
return true;
}
Run Code Online (Sandbox Code Playgroud)
有没有更快的方法来测试两个只有属性的对象是否具有相同的值(每个属性不需要一行代码或一个逻辑表达式?)
切换到结构不是一种选择.
我正在开发一个mvc3网络应用程序.当用户更新某些内容时,我想将旧数据与用户输入的新数据进行比较,并且对于每个不同的字段,将这些数据添加到日志中以创建活动日志.
现在这是我的保存动作:
[HttpPost]
public RedirectToRouteResult SaveSingleEdit(CompLang newcomplang)
{
var oldCompLang = _db.CompLangs.First(x => x.Id == newcomplang.Id);
_db.CompLangs.Attach(oldCompLang);
newcomplang.LastUpdate = DateTime.Today;
_db.CompLangs.ApplyCurrentValues(newcomplang);
_db.SaveChanges();
var comp = _db.CompLangs.First(x => x.Id == newcomplang.Id);
return RedirectToAction("ViewSingleEdit", comp);
}
Run Code Online (Sandbox Code Playgroud)
我发现我可以用它来遍历我的oldCompLang属性:
var oldpropertyInfos = oldCompLang.GetType().GetProperties();
Run Code Online (Sandbox Code Playgroud)
但这并没有真正帮助,因为它只显示属性(Id,Name,Status ...)而不是这些属性的值(1,Hello,Ready ...).
我可以走得那么艰难:
if (oldCompLang.Status != newcomplang.Status)
{
// Add to my activity log table something for this scenario
}
Run Code Online (Sandbox Code Playgroud)
但我真的不想为对象的所有属性做这件事.
我不确定迭代两个对象以查找不匹配的最佳方法是什么(例如,用户更改了名称或状态......)并根据我可以存储在另一个表中的差异构建列表.
.NET结构中的成员相等性测试使用的算法是什么?我想知道这一点,以便我可以使用它作为我自己的算法的基础.
我试图为任意对象(在C#中)编写递归成员相等性测试,以测试DTO的逻辑相等性.如果DTO是结构体,这是相当容易的(因为ValueType.Equals主要是正确的事情),但这并不总是合适的.我还想覆盖任何IEnumerable对象(但不是字符串!)的比较,以便比较它们的内容而不是它们的属性.
事实证明这比我预期的要难.任何提示将不胜感激.我会接受证明最有用的答案或提供最有用信息的链接.
谢谢.
给定一个具有35个字段的类和2个具有一定数量的不同字段值的对象.是否有一种聪明的方法来获取列表<String>以及对象如下所示的字段名称?
例如
obj1.Name = "aaa";
obj1.LastName = "bbb";
obj1.Address = "xcs";
obj2.Name = "aaa";
obj2.LastName = "ccc";
obj2.Address = "jk";
Run Code Online (Sandbox Code Playgroud)
目的:
list<<String>String> containing 2 Strings LastName and Address
Run Code Online (Sandbox Code Playgroud)
我认为反射是要走的路,但是35场,恐怕太重了.还有其他想法,比如linq?
我从同一个类中获得了两个对象,我需要逐个字段地比较它们.问题在于它们有近百个字段,手工编写这些字段是很有帮助的.
你知道怎么做更简单的方法吗?Java中的反思可能是一个解决方案,但在我看来,它似乎是一个黑客.毕竟我寻求一个C#解决方案.
我有一个类,它包含一些字符串成员,一些双成员和一些数组对象.
我创建了这个类的两个对象,是否有任何最简单,有效的方法来比较这些对象并说它们相等?有什么建议?
我知道如何编写比较函数,但这会耗费时间.
c# ×8
.net ×5
equality ×2
equals ×2
reflection ×2
asp.net-mvc ×1
auditing ×1
compare ×1
comparison ×1
dto ×1
lambda ×1
linq ×1
linq-to-sql ×1
overriding ×1