【问题标题】:C# Compare two object valuesC#比较两个对象值
【发布时间】:2018-01-20 03:57:48
【问题描述】:

我目前有两个对象(相同类型),它们可以表示任何原始值,例如字符串、整数、日期时间等。

var valueX = ...;
var valueY = ...;

Atm 我像这样在字符串级别上比较它们

var result = string.Compare(fieldValueX.ToString(), fieldValueY.ToString(), StringComparison.Ordinal);

但我需要在类型级别上比较它们(如果它们恰好是整数,则为整数

int i = 0;
int j = 2;
i.CompareTo(j);

,作为日期,如果它们恰好是日期等),类似于

object.Compare(x,y);

以同样的方式返回 -1,0,1。有什么方法可以实现?

【问题讨论】:

  • 其中一个可以为空吗?如果没有,你可以使用((IComparable)x).CompareTo(y)
  • Object.Equal 不起作用吗?它将返回 bool 而不是 int
  • But I need to compare them on type level (as ints if those happen to be ints... Minimal, Complete, and Verifiable example,以便更好地说明您的问题。

标签: c# .net


【解决方案1】:

感谢您的回答,正确的方法是检查对象是否实现 IComparable 以及是否实现 - 进行类型转换并调用 CompareTo

if (valueX is IComparable)
{
     var compareResult = ((IComparable)valueX).CompareTo((IComparable)valueY);
}

【讨论】:

    【解决方案2】:

    Object1.Equals(obj1, obj2) 不会工作,除非 @object 引用同一个对象。

    EG:

    var obj1 = new MyObject();
    var obj2 = new MyObject();
    

    这将为Object1.Equals(obj1, obj2) 返回“False”,因为它们是不同的参考

    var obj1 = new MyObject();
    var obj2 = obj1;
    

    这将为Object1.Equals(obj1, obj2) 返回“True”,因为它们是相同的参考。

    解决方案: 您很可能需要编写一个覆盖 Object.Equals 的扩展方法。可以为特定类型 (See here for custom object comparer:) 创建自定义对象比较器,也可以动态检查每个属性并进行比较。

    【讨论】:

      【解决方案3】:

      有几个选项可以做到这一点。

      覆盖 Object.Equal

      您可以覆盖类中的 Object.Equal() 方法,然后确定是什么使对象在那里相等。这也可以让您巧妙地决定要比较什么,因为看起来这些对象可以是多种数据类型。在此覆盖中,您需要处理每种可能的情况。您可以在此处阅读有关此选项的更多信息:

      https://msdn.microsoft.com/en-us/library/bsc2ak47(v=vs.110).aspx

      需要注意的是,默认情况下,Object.Equal() 会比较你的对象引用。

      实现 IComparable

      IComparable 是一个简洁的接口,它提供了一个对象Compare。正如 cmets 所提到的,这将让您定义如何根据您想要的任何标准来比较对象。

      这里介绍了这个选项:https://msdn.microsoft.com/en-us/library/system.icomparable(v=vs.110).aspx

      实现 CompareBy() 方法

      另外,您可以为每种可能的类型实现方法,即CompareByInt()CompareByString(),但这种方法取决于您知道在执行此操作时将拥有什么。这也会产生负面影响,使代码更难维护,因为涉及的方法更多。

      【讨论】:

        【解决方案4】:

        您可以使用Compare 方法编写GeneralComparer,并根据需要进行重载。 对于必须执行标准比较的类型,您可以使用EqualityComparer<T>.Default;对于其他类型,您编写自己的比较函数。这是一个示例:

        static class GeneralComparer
        {
            public static int Compare(int x, int y)
            {
                //for int, use the standard comparison:
                return EqualityComparer<int>.Default.Equals(x, y);
            }
        
            public static int Compare(string x, string y)
            {
                //for string, use custom comparison:
                return string.Compare(x, y, StringComparison.Ordinal);
            }
        
            //overload for DateTime
            //overload for MyType
            //overload for object
            //...
        }
        

        在运行时选择正确的重载。 有一个缺点:如果将两个 int(或其他特定类型)声明为对象,则会调用 object 重载:

        object a = 2;
        object b = 3;
        //this will call the "Compare(object x, object y)" overload!
        int comparison = GeneralComparer.Compare(a, b); 
        

        【讨论】:

          【解决方案5】:

          将对象转换为字典,然后按照数学集概念减去它们,结果项应该为空,以防它们相同。

          public static IDictionary<string, object> ToDictionary(this object source)
              {
                  var fields = source.GetType().GetFields(
                      BindingFlags.GetField |
                      BindingFlags.Public |
                      BindingFlags.Instance).ToDictionary
                  (
                      propInfo => propInfo.Name,
                      propInfo => propInfo.GetValue(source) ?? string.Empty
                  );
          
                  var properties = source.GetType().GetProperties(
                      BindingFlags.GetField |
                      BindingFlags.GetProperty |
                      BindingFlags.Public |
                      BindingFlags.Instance).ToDictionary
                  (
                      propInfo => propInfo.Name,
                      propInfo => propInfo.GetValue(source, null) ?? string.Empty
                  );
          
                  return fields.Concat(properties).ToDictionary(key => key.Key, value => value.Value); ;
              }
              public static bool EqualsByValue(this object source, object destination)
              {
                  var firstDic = source.ToFlattenDictionary();
                  var secondDic = destination.ToFlattenDictionary();
                  if (firstDic.Count != secondDic.Count)
                      return false;
                  if (firstDic.Keys.Except(secondDic.Keys).Any())
                      return false;
                  if (secondDic.Keys.Except(firstDic.Keys).Any())
                      return false;
                  return firstDic.All(pair =>
                    pair.Value.ToString().Equals(secondDic[pair.Key].ToString())
                  );
              }
              public static bool IsAnonymousType(this object instance)
              {
          
                  if (instance == null)
                      return false;
          
                  return instance.GetType().Namespace == null;
              }
              public static IDictionary<string, object> ToFlattenDictionary(this object source, string parentPropertyKey = null, IDictionary<string, object> parentPropertyValue = null)
              {
                  var propsDic = parentPropertyValue ?? new Dictionary<string, object>();
                  foreach (var item in source.ToDictionary())
                  {
                      var key = string.IsNullOrEmpty(parentPropertyKey) ? item.Key : $"{parentPropertyKey}.{item.Key}";
                      if (item.Value.IsAnonymousType())
                          return item.Value.ToFlattenDictionary(key, propsDic);
                      else
                          propsDic.Add(key, item.Value);
                  }
                  return propsDic;
              }
          originalObj.EqualsByValue(messageBody); // will compare values.
          

          source of the code

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-07-10
            • 2013-05-06
            • 2021-03-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-04-18
            相关资源
            最近更新 更多