Domanda

Riferendosi alla domanda che ho chiesto in precedenza: Confronta due elenchi che contengono molti oggetti

.

È impressionante vedere quanto velocemente il confronto è Maider implementando l'interfaccia IugualityComparer: Esempio qui

Come ho detto nella mia altra domanda questo confronto mi aiuta a eseguire il backup di una cartella GUSTA su una cartella di destinazione. Sapere che voglio sincronizzare le cartelle, quindi ho bisogno di confrontare le date dei file. Ogni volta che faccio qualcosa come:

public class MyFileComparer2 : IEqualityComparer<MyFile>
{

    public bool Equals(MyFile s, MyFile d)
    {
        return
            s.compareName.Equals(d.compareName) &&
            s.size == d.size &&
            s.deepness == d.deepness &&
            s.dateModified.Date <= d.dateModified.Date;  // This line does not work. 
            // I also tried comparing the strings by converting it to a string and it does
            // not work. It does not give me an error but it does not seem to include the files
            // where s.dateModified.Date < d.dateModified.Date

    }

    public int GetHashCode(MyFile a)
    {
        int rt = (a.compareName.GetHashCode() * 251 + a.size.GetHashCode() * 251 + a.deepness.GetHashCode() + a.dateModified.Date.GetHashCode());

        return rt;

    }
}
.

sarà bello se potessi fare qualcosa di simile usando più grande o uguale dei segni. Ho anche provato a usare la proprietà di spunta e non funziona. Forse sto facendo qualcosa di sbagliato. Credo che non sia possibile confrontare le cose con il segno inferiore a uguali implementazione di questa interfaccia. Inoltre, non capisco come funziona questa classe; So solo che è impressionante quanto velocemente intera attraverso l'intera lista.

È stato utile?

Soluzione

Poiché gli oggetti DateTime sono diversi nel caso in cui un datetime è inferiore all'altro, si ottengono diversi hashcode per gli oggetti s e d e il metodo uguale ènon chiamato.Affinché il tuo confronto delle date funzioni, è necessario rimuovere la parte della data dal metodo GetHashCode:

public int GetHashCode(MyFile a)
{
    int rt = ((a.compareName.GetHashCode() * 251 + a.size.GetHashCode())
                          * 251 + a.deepness.GetHashCode()) *251;

    return rt;

}
.

Altri suggerimenti

Il tuo approccio intero è fondamentale imperfetto perché il tuo metodo IEqualityComparer.Equals non è simmetrico. Ciò significa Equals(file1, file2) non è uguale Equals(file2, file1) a causa del modo in cui si sta utilizzando meno dell'operatore.

La documentazione:

    .
  • iegualitycomparer.ecals Metodo .

    afferma chiaramente:

    .

    Notes to Implementer

    Il metodo Equals è riflessivo, simmetrico e transitivo. Cioè, restituisce vero se usato per confrontare un oggetto con se stesso; vero per due oggetti x e y se è vero per y e x; e TRUE per due oggetti X e Z se è vero per X e Y e anche vero per Y e Z.

    Le implementazioni sono necessarie per assicurarsi che se il metodo Equals restituisca true per due oggetti X e Y, il valore restituito dal metodo GetHashCode per X deve essere uguale al valore restituito per Y.

    Invece è necessario utilizzare l'interfaccia IComparable o il IEqualityComparer in combinazione con comparezioni della data. Se non lo fai, le cose potrebbero sembrare lavorare per un po 'ma ti pentirai più tardi.

Il tuo gethashcode ha un problema:

public int GetHashCode(MyFile a)
{
    int rt = (((a.compareName.GetHashCode() * 251) 
           + a.size.GetHashCode() * 251)
           + a.deepness.GetHashCode() *251) 
           + a.dateModified.Date.GetHashCode();

    return rt;

}
.

Ho cambiato la parte della data perché avevo anche bisogno del tempo pertanto uso invece la proprietà dei ticks.Mi sono sbarazzato del codice hashed da dati e funziona alla grande.Ecco come ho modificato il mio programma.Avevo problemi a confrontare le date perciò ho usato la proprietà dei ticks.

public class MyFileComparer2 : IEqualityComparer<MyFile>
{

    public bool Equals(MyFile s, MyFile d)
    {
        return
            s.compareName.Equals(d.compareName) &&
            s.size == d.size &&
            s.deepness == d.deepness &&
            //s.dateModified.Date <= d.dateModified.Date &&
            s.dateModified.Ticks >= d.dateModified.Ticks
            ;  

    }

    public int GetHashCode(MyFile a)
    {
        int rt = (((a.compareName.GetHashCode() * 251)
                + a.size.GetHashCode() * 251)
                + a.deepness.GetHashCode() * 251)
                //+ a.dateModified.Ticks.GetHashCode();                       
                ;

        return rt;

    }
}
.

Non so ancora come funziona questa funzione codice hash.La cosa bella è che funziona alla grande.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top