比较两个结构体 C# 中的值

发布于 2024-07-23 22:42:18 字数 1613 浏览 6 评论 0原文

我不是在寻找返回 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());
    }
}

我想知道是否有一种方法可以通过某种序列化来执行此操作,或者这是否是实际查看哪些值已更改的唯一方法。 即使有更好的方法来实现 Compare 函数,我也会采用。

I'm not looking for a comparison of two structs that returns bool, I am wondering if there is a way to get which fields of two structs (the same structure, but maybe different values) are different. Basically I want a simpler way to do the following:

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());
    }
}

I'm wondering if there is a way to do this with serialization of some sort, or if this is the only way to actually see which values have changed. Even if there is a better way to implement the Compare function, I would take that too.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

青芜 2024-07-30 22:42:18

林克?

  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();  
  }  

Linq?

  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();  
  }  
人心善变 2024-07-30 22:42:18

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

如果您想要该值并且您有 FieldInfo...

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

另外,

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

GetProperties() 返回属性。

I can't add comments yet, so in response to SwDevMan81 up above there a bit ^

If you want the value and you have a FieldInfo...

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

Also,

GetFields() returns member variables. The flags control if you want public/private/static etc members.

GetProperties() returns properties.

怂人 2024-07-30 22:42:18

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

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 类和额外代码。 还有比这更简单的方法吗?

Ok, so using the information for peoples posts, we would have a new compare method that looks like this:

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;
}

This seems to significantly reduce the size of the compare function, but I still have all the Diffs class and extra code. Is there a simpler way than this still?

伏妖词 2024-07-30 22:42:18

可以使用反射来完成。 检查 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);
    }

It can be done using Reflection. Check for FieldInfo and PropertyInfo examples.

MSDN example (modified a bit):

    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);
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文