5

我不是在寻找返回 bool 的两个结构的比较,我想知道是否有办法获取两个结构的哪些字段(相同的结构,但可能是不同的值)是不同的。基本上我想要一种更简单的方法来执行以下操作:

public class Diff
{
    public String VarName;
    public object Val1;
    public object Val2;

    public Diff(String varName, object val1, object val2)
    {
        VarName = varName;
        Val1 = val1;
        Val2 = val2;
    }

    public override string ToString()
    {
        return VarName + " differs with values " + Val1 + " and " + Val2;
    }
}

public struct TestStruct
{
    public int ValueOne;
    public int ValueTwo;
    public int ValueThree;

    public List Compare(TestStruct inTestStruct)
    {
        List diffs = new List();
        if (ValueOne != inTestStruct.ValueOne)
        {
            diffs.Add(new Diff("ValueOne", ValueOne, inTestStruct.ValueOne));
        }
        if (ValueTwo != inTestStruct.ValueTwo)
        {
            diffs.Add(new Diff("ValueTwo", ValueTwo, inTestStruct.ValueTwo));
        }
        if (ValueThree != inTestStruct.ValueThree)
        {
            diffs.Add(new Diff("ValueThree", ValueThree, inTestStruct.ValueThree));
        }
        return diffs;
    }
}

public CompareStructsExample()
{
    TestStruct t1 = new TestStruct();
    t1.ValueOne = 1;
    t1.ValueTwo = 8;
    t1.ValueThree = 5;

    TestStruct t2 = new TestStruct();
    t2.ValueOne = 3;
    t2.ValueTwo = 8;
    t2.ValueThree = 7;

    List diffs = t1.Compare(t2);
    foreach (Diff d in diffs)
    {
        System.Console.WriteLine(d.ToString());
    }
}

我想知道是否有办法通过某种序列化来做到这一点,或者这是否是实际查看哪些值已更改的唯一方法。即使有更好的方法来实现比较功能,我也会接受。

4

4 回答 4

10

可以使用反射来完成。检查FieldInfoPropertyInfo示例。

MSDN 示例(稍作修改):

    Type myType = typeof(TestStruct);

    // Get the fields of TestStruct.
    FieldInfo[] myFieldInfo = 
        myType.GetFields(
           BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);

    Console.WriteLine("\nThe fields of TestStruct are \n");

    // Display the field information of TestStruct.
    for(int i = 0; i < myFieldInfo.Length; i++)
    {
        Console.WriteLine("\nName            : {0}", myFieldInfo[i].Name);
        Console.WriteLine("Declaring Type  : {0}", myFieldInfo[i].DeclaringType);
        Console.WriteLine("IsPublic        : {0}", myFieldInfo[i].IsPublic);
        Console.WriteLine("MemberType      : {0}", myFieldInfo[i].MemberType);
        Console.WriteLine("FieldType       : {0}", myFieldInfo[i].FieldType);
        Console.WriteLine("IsFamily        : {0}", myFieldInfo[i].IsFamily);
    }
于 2009-06-11T20:19:09.487 回答
1

林克?

  public List<string> Compare(TestStruct x, TestStruct y) {  
    return (  
      from l1 in x.GetType().GetFields()  
      join l2 in y.GetType().GetFields() on l1.Name equals l2.Name  
      where !l1.GetValue(x).Equals(l2.GetValue(y))  
      select string.Format("{0} {1} {2}", l1.Name, l1.GetValue(x), l2.GetValue(y))  
    ).ToList();  
  }  
于 2009-06-17T11:52:35.707 回答
1

我还不能添加评论,所以响应上面的SwDevMan81有点^

如果你想要这个值并且你有一个 FieldInfo...

object val = myFieldInfo[i].GetValue(Obj);

还,

GetFields()返回成员变量。标志控制是否需要公共/私有/静态等成员。

GetProperties()返回属性。

于 2009-06-11T20:54:57.667 回答
0

好的,所以使用人们帖子的信息,我们将有一个新的比较方法,如下所示:

public List Compare2(TestStruct inTestStruct)
{
  List diffs = new List();

  FieldInfo[] fields = this.GetType().GetFields();
  FieldInfo[] fields2 = inTestStruct.GetType().GetFields();

  for (int i = 0; i < fields.Length; i++)
  {
     object value1 = fields[i].GetValue(this);
     object value2 = fields2[i].GetValue(inTestStruct);
     if (!value1.Equals(value2))
     {
        diffs.Add(new Diff(fields[i].Name, value1, value2));
     }
  }
  return diffs;
}

这似乎显着减小了比较函数的大小,但我仍然拥有所有 Diffs 类和额外代码。还有比这更简单的方法吗?

于 2009-06-11T21:02:56.027 回答