2012-03-20 102 views
-1

属性的值,我认为我有拳击发出比较在两种情况下

foreach(var p in item.GetType().GetProperties(). 
    Where(p => p.GetValue(original, null) is ValueType)) 
{ 
    var originalValue = p.GetValue(original, null); 
    var modifiedValue = p.GetValue(item, null); 
    if (!originalValue.Equals(modifiedValue)) 
     kvpData.AppendFormat("{0}={1}&", p.Name, originalValue); 
} 

originalValue是永远等于modifiedValue,即时猜测那是因为他们在里面对象盒装。但是,我该如何解决它?

+0

这些属性是什么类型? – 2012-03-20 14:53:07

+0

请显示一个简短但完整的程序来演示问题。 – 2012-03-20 14:53:19

+0

您确定原始文件和项目是不同的实例并具有不同的属性值吗?我尝试了使用简单对象的方法,如'var original = new TestObject(){Test = 1}; var item = new TestObject(){Test = 2};'它起作用。 – Nikolay 2012-03-20 14:56:38

回答

1

这不是一个拳击问题。 Equals是一个虚拟方法,盒装值类型重写就好了。

但是,我不确定问题是什么。难道实际上没有任何匹配的属性?请记住GetProperties()没有任何参数将只返回公共属性。如果你需要的属性是私人,你需要添加一些BindingFlags

GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) 

(我假设在这里,你不想静态属性。)

你是不是也确保它实际上是属性你以后而不是字段?请记住,如果你声明的东西作为

public string Name; 

那么它是一个,而

public string Name { get; set; } 

财产。如果它实际上是您需要的字段,则需要使用GetFields()而不是GetProperties(),并使用相同的绑定标志。

-1

MSDN: Object.Equals

的Equals的默认实现支持值类型 引用类型引用相等,和位平等。参考 相等意味着被比较的对象引用指的是同一对象的 。按位相等意味着被比较的对象具有相同的二进制表示。

这意味着,在你的情况下,这2个对象(如果它们是引用类型)永远不会指向同一个实例。

有没有一种简单的方法来解决这个如此通用的方式,如你所愿。

但你可以实现(只是一个例子)的IComparable对这些类型你要去进行比较,之后在这个迭代检查,如果该值的类型rturned该接口,所以演员和调用它的实施IComparable.CompareTo方法实现。

可以检查对象实现指定interfacce,在当前的情况下IComparable的,你可以做这样的事情:

originalValue .GetType().GetInterfaces().Any(x => 
    x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IComparable)) 

希望这有助于。

+0

@downvoter:谨慎解释对此的downvote? – Tigran 2012-03-20 15:10:29

+0

我在想你可能会被downvoted,因为问题中提出的代码已经试图将对象限制为ValueType,这意味着它最好使用ValueType.Equals。 – JamieSee 2012-03-20 15:15:36

+0

@JamieSee:如果是这样,这是完全错误的假设。因为我清楚地建议为参考类型实现IComparable并执行其方法。如果这个标记是用值类型来代替的,那么它就清楚地表明这些值永远不会相等(查看OP的问题)。所以使用* this *代码没有错,但错误的代码称它。 – Tigran 2012-03-20 15:19:37

0

Linq是一个很棒的工具,但我不确定你为什么在这里使用它。你实际上导致这组属性迭代两次,这非常昂贵。我会写没有Linq的代码。而且,不需要多次获得价值,这又是非常昂贵的。试试这个代码。它避免了我指出的缺陷,并正确进行比较时,我制造和测试的虚拟类是:

foreach(PropertyInfo p in item.GetType().GetProperties()) 
    { 
     if (p.PropertyType.BaseType == typeof(ValueType) || p.PropertyType == typeof(string)) 
     { 
      var originalValue = p.GetValue(original, null); 
      var modifiedValue = p.GetValue(item, null); 
      if (originalValue != modifiedValue) kvpData.AppendFormat("{0}={1}&", p.Name, originalValue); 
     } 
    } 

另外请注意,虽然他们实现价值比较字符串不是一个值类型。

相关问题