Prévention de la liste en double & lt; T & gt; Entrées
J'espère être en mesure de faire un travail autour, mais je ne peux pas pour la vie de me comprendre pourquoi ce code ne fonctionne pas correctement et permettant des entrées en double pour être ajouté à la Liste.
La if
déclaration condition n'est jamais remplie, même si je fais glisser les fichiers identiques dans le même emplacement. Je ne comprends pas pourquoi la "Contient" la méthode n'est pas de correspondance.
public class Form1:Form {
private List<FileInfo> dragDropFiles = new List<FileInfo>();
private void Form1_DragDrop(object sender, DragEventArgs e) {
try {
if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
string[] files =
(string[])e.Data.GetData(DataFormats.FileDrop);
OutputDragDrop(files);
}
}
catch { }
}
private void Form1_DragEnter(object sender, DragEventArgs e) {
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.None;
}
private void OutputDragDrop(string[] files) {
try {
foreach (string file in files) {
FileInfo fileInfo = new FileInfo(file);
if (dragDropFiles.Contains(fileInfo)) {
dragDropFiles.Remove(fileInfo);
}
dragDropFiles.Add(fileInfo);
}
PopulateContextMenu();
}
catch { }
}
}
Je pensais que j'avais trouvé une autre méthode pour réaliser cela à l'aide de "Distinct"
Cependant, il semble checkedDragDropFiles
& dragDropFiles
ont la même quantité de bulletins de participation, y compris les doublons, sauf lorsque dragDropFiles
est affiché dans une ListBox
il ne les indique pas. Pourquoi faut-il faire cela?
J'ai besoin de prévenir toute dupliqué les entrées de la liste, que je serais par programme la création d'un menu basé sur les données de la liste.
private void OutputDragDrop(string[] files)
{
try
{
foreach (string file in files)
{
FileInfo fileInfo = new FileInfo(file);
//if (dragDropFiles.Contains(fileInfo))
//{
// dragDropFiles.Remove(fileInfo);
//}
dragDropFiles.Add(fileInfo);
}
List<FileInfo> checkedDragDropFiles = dragDropFiles.Distinct().ToList();
debugList.DataSource = checkedDragDropFiles;
debugList2.DataSource = dragDropFiles;
//PopulateContextMenu();
}
catch { }
}
source d'informationauteur negligible | 2012-01-11
Vous devez vous connecter pour publier un commentaire.
List<T>
en effet, d'autoriser les doublons.Dans le cas de
FileInfo
leContains
méthode sera de vérifier si les références sont les mêmes, mais comme vous récupérer complètement nouveau ensemble deFileInfo
les références sont différentes.Vous avez besoin d'utiliser la surcharge de
Contains
qui prend unIEqualityComparer
- voir ici.Vous pouvez également utiliser
HashSet<T>
au lieu - c'est une structure de données qui ne permet pas de doublons (mais avec des références différentes, vous aurez toujours ce problème).Car la valeur par défaut
Object.Equals
de mise en œuvre de comparer des objets par référence et non par valeur. ChaqueFileInfo
exemple, vous créez un objet différent, dans la mesure où .NET est concerné.Vous pouvez utiliser LINQ pour spécifier votre comparaison personnalisée de prédicat pour comparer des objets en propriété différente:
[Modifier]
Depuis les chaînes sont comparées à la valeur, vous pourriez aussi bien filtrer la liste avant vous projet à
FileInfo
comme ceci:Vous pouvez facilement créer plusieurs FileInfo cas pour le même fichier - si votre liste contient tous les FileInfo qu'une seule fois, mais il peut y avoir plusieurs FileInfos pour le smae fichier.
Alors votre meilleur pari pourrait être d'utiliser une table de hachage et de l'utilisation FileInfo.FullName comme critère.
Si vous voulez une mise en œuvre de
ICollection<T>
qui ne permettent pas de doublons, tout en conservant une commande, pensez à utiliserSortedSet<T>
plutôt queList<T>
.