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.
To find out if they are the same object, compare pointers to the two structs for equality. If you want to find out in general if they have the same value you have to do a deep comparison. This involves comparing all the members. If the members are pointers to other structs you need to recurse into those structs too.
Yes, you can assign one instance of a struct to another using a simple assignment statement.
We should not compare structures because of the holes between the member fields of a structure. Comparing the structures themselves as variables won`t work.
Yeah. It is relational operator. Relational operators are only used to compare two or more things.
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);
}
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();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With