对象属性在C#中的比较 [英] Comparing object properties in c#

查看:151
本文介绍了对象属性在C#中的比较的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我想出作为许多我的其他类的继承一个类的方法。我们的想法是,它允许在同一类型的对象的特性之间的简单比较

现在,这样做的工作 - 但在提高我的code品质的利益,我想我会扔出去审议。它如何能够更好/更高效的/ etc?

  ///<总结>
///比较属性值(字符串)
///< /总结>
///< PARAM NAME =目标文件>< /参数>
///<&回报GT;< /回报>
公共BOOL PropertiesEqual(对象comparisonObject)
{    类型sourceType的= this.GetType();
    键入destinationType = comparisonObject.GetType();    如果(sourceType的== destinationType)
    {
        的PropertyInfo [] = sourceProperties sourceType.GetProperties();
        的foreach(在sourceProperties的PropertyInfo PI)
        {
            如果((sourceType.GetProperty(pi.Name).GetValue(这一点,空)== NULL和放大器;&安培; destinationType.GetProperty(pi.Name).GetValue(comparisonObject,NULL)== NULL))
            {
                //如果两个都为空,不要试图比较(抛出异常)
            }
            否则,如果(!(sourceType.GetProperty(pi.Name).GetValue(这一点,空)的ToString()== destinationType.GetProperty(pi.Name).GetValue(comparisonObject,空)的ToString()))
            {
                //只需要一个属性是不同的失败等于。
                返回false;
            }
        }
    }
    其他
    {
        抛出新的ArgumentException(比较对象必须是同一类型。,comparisonObject);
    }    返回true;
}


解决方案

我一直在寻找code,会做类似的事情,以帮助写单元测试的一个片段。以下是我最终使用。

 公共静态布尔PublicInstancePropertiesEqual< T>(T自我,T于PARAMS字符串[]无视)其中T:类
  {
     如果(自= NULL&放大器;!&安培;!为= NULL)
     {
        类型type = typeof运算(T);
        清单<串GT; ignoreList =新的List<串GT;(忽略);
        的foreach(System.Reflection.PropertyInfo PI在type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance))
        {
           如果(!ignoreList.Contains(pi.Name))
           {
              反对selfValue = type.GetProperty(pi.Name).GetValue(个体经营,NULL);
              反对toValue = type.GetProperty(pi.Name).GetValue(到,NULL);              如果(selfValue = toValue和放大器;!及(selfValue == NULL || selfValue.Equals(toValue))!)
              {
                 返回false;
              }
           }
        }
        返回true;
     }
     返回self ==来;
  }

编辑:

同code同上,但使用LINQ和扩展方法:

 公共静态布尔PublicInstancePropertiesEqual< T>(这件T自我,T于PARAMS字符串[]无视)其中T:类
{
    如果(自= NULL&放大器;!&安培;!为= NULL)
    {
        VAR类型= ty​​peof运算(T);
        VAR ignoreList =新的List<串GT;(忽略);
        VAR unequalProperties =
            从type.GetProperties PI(BindingFlags.Public | BindingFlags.Instance)
            哪里!ignoreList.Contains(pi.Name)
            让selfValue = type.GetProperty(pi.Name).GetValue(个体经营,NULL)
            让toValue = type.GetProperty(pi.Name).GetValue(于零)
            其中,selfValue = toValue和放大器;!&安培; (selfValue == NULL ||!selfValue.Equals(toValue))
            选择selfValue;
        返回unequalProperties.Any()!;
    }
    返回self ==来;
}

This is what I've come up with as a method on a class inherited by many of my other classes. The idea is that it allows the simple comparison between properties of Objects of the same Type.

Now, this does work - but in the interest of improving the quality of my code I thought I'd throw it out for scrutiny. How can it be better/more efficient/etc.?

/// <summary>
/// Compare property values (as strings)
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public bool PropertiesEqual(object comparisonObject)
{

    Type sourceType = this.GetType();
    Type destinationType = comparisonObject.GetType();

    if (sourceType == destinationType)
    {
        PropertyInfo[] sourceProperties = sourceType.GetProperties();
        foreach (PropertyInfo pi in sourceProperties)
        {
            if ((sourceType.GetProperty(pi.Name).GetValue(this, null) == null && destinationType.GetProperty(pi.Name).GetValue(comparisonObject, null) == null))
            {
                // if both are null, don't try to compare  (throws exception)
            }
            else if (!(sourceType.GetProperty(pi.Name).GetValue(this, null).ToString() == destinationType.GetProperty(pi.Name).GetValue(comparisonObject, null).ToString()))
            {
                // only need one property to be different to fail Equals.
                return false;
            }
        }
    }
    else
    {
        throw new ArgumentException("Comparison object must be of the same type.","comparisonObject");
    }

    return true;
}

解决方案

I was looking for a snippet of code that would do something similar to help with writing unit test. Here is what I ended up using.

public static bool PublicInstancePropertiesEqual<T>(T self, T to, params string[] ignore) where T : class 
  {
     if (self != null && to != null)
     {
        Type type = typeof(T);
        List<string> ignoreList = new List<string>(ignore);
        foreach (System.Reflection.PropertyInfo pi in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance))
        {
           if (!ignoreList.Contains(pi.Name))
           {
              object selfValue = type.GetProperty(pi.Name).GetValue(self, null);
              object toValue = type.GetProperty(pi.Name).GetValue(to, null);

              if (selfValue != toValue && (selfValue == null || !selfValue.Equals(toValue)))
              {
                 return false;
              }
           }
        }
        return true;
     }
     return self == to;
  }

EDIT:

Same code as above but uses LINQ and Extension methods :

public static bool PublicInstancePropertiesEqual<T>(this T self, T to, params string[] ignore) where T : class
{
    if (self != null && to != null)
    {
        var type = typeof(T);
        var ignoreList = new List<string>(ignore);
        var unequalProperties =
            from pi in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)
            where !ignoreList.Contains(pi.Name)
            let selfValue = type.GetProperty(pi.Name).GetValue(self, null)
            let toValue = type.GetProperty(pi.Name).GetValue(to, null)
            where selfValue != toValue && (selfValue == null || !selfValue.Equals(toValue))
            select selfValue;
        return !unequalProperties.Any();
    }
    return self == to;
}

这篇关于对象属性在C#中的比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆