Sammenligne to structs verdier i C #

stemmer
5

Jeg er ikke ute etter en sammenligning av to structs som returnerer bool, jeg lurer på om det er en måte å få hvilke felt av to structs (samme struktur, men kanskje forskjellige verdier) er forskjellige. I utgangspunktet ønsker jeg en enklere måte å gjøre følgende:

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

Jeg lurer på om det er en måte å gjøre dette med serialisering av noe slag, eller om dette er den eneste måten å faktisk se hvilke verdier som er endret. Selv om det er en bedre måte å implementere sammenligning funksjon, ville jeg ta det også.

Publisert på 11/06/2009 klokken 20:16
kilden bruker
På andre språk...                            


4 svar

stemmer
10

Det kan gjøres ved hjelp av refleksjon. Sjekk for FieldInfo og PropertyInfo eksempler.

MSDN eksempel (modifisert litt):

    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);
    }
Svarte 11/06/2009 kl. 20:19
kilden bruker

stemmer
1

Jeg kan ikke legge til kommentarer ennå, så svar på SwDevMan81 opp over det litt ^

Hvis du vil at verdien og du har en FieldInfo ...

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

Også,

GetFields()returnerer medlem variabler. Flaggene bestemme om du vil offentlige / private / statisk etc medlemmer.

GetProperties() returnerer egenskaper.

Svarte 11/06/2009 kl. 20:54
kilden bruker

stemmer
0

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();  
  }  
Svarte 17/06/2009 kl. 11:52
kilden bruker

stemmer
0

Ok, så å bruke informasjonen til folks innlegg, ville vi ha en ny sammenligne metode som ser slik ut:

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

Dette ser ut til å redusere størrelsen på sammenligne funksjon, men jeg har fortsatt alle differ klasse og ekstra kode. Finnes det en enklere måte enn dette fortsatt?

Svarte 11/06/2009 kl. 21:02
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more