2010-07-01 19 views
7

Powiel możliwe:
How to check whether 2 DirectoryInfo objects are pointing to the same directory?Dlaczego to porównanie DirectoryInfo nie działa?

var dirUserSelected = new DirectoryInfo(Path.GetDirectoryName("SOME PATH")); 
var dirWorkingFolder = new DirectoryInfo(Path.GetDirectoryName("SAME PATH AS ABOVE")); 

if (dirUserSelected == dirWorkingFolder) 
{ 
    //this is skipped 
} 

if (dirUserSelected.Equals(dirWorkingFolder)) 
{ 
    //this is skipped 
} 

Podczas debugowania, mogę badać wartości w każdym i są one równe. Zgaduję, że to jest inny bywalec, by nieporozumienie ... Proszę kogoś, jak mogę porównać te dwie rzeczy?

+2

Jaki jest powód porównywania obiektów DirectoryInfo? Może powinieneś porównać .FullPath? – griZZZly8

+0

To nie są te same ścieżki. Czy to jakiś test Stroopa? –

+2

Również twoje klamry są komentowane. Jeśli chcesz, abyśmy włożyli energię, aby ci pomóc, czy nie wkładasz energii w zadawanie dobrych pytań? –

Odpowiedz

9

wierzę, że chcesz to zrobić:

var dirUserSelected = new DirectoryInfo(Path.GetDirectoryName(@"c:\some\path\")); 
var dirWorkingFolder = new DirectoryInfo(Path.GetDirectoryName(@"c:\Some\PATH")); 

if (dirUserSelected.FullName == dirWorkingFolder.FullName) 
{ // this will be skipped, 
    // since the first string contains an ending "\" and the other doesn't 
    // and the casing in the second differs from the first 
} 

// to be sure all things are equal; 
// either build string like this (or strip last char if its a separator) 
// and compare without considering casing (or ToLower when constructing) 
var strA = Path.Combine(dirUserSelected.Parent, dirUserSelected.Name); 
var strB = Path.Combine(dirWorkingFolder.Parent, dirWorkingFolder.Name); 
if (strA.Equals(strB, StringComparison.CurrentCultureIgnoreCase) 
{ //this will not be skipped 
} 

............ 

w was przykład porównujesz 2 różne przedmioty to dlaczego nie są one równe. Uważam, że musisz porównać Parts, więc użyj powyższego kodu.

+1

Należy pamiętać, że te same dwie ścieżki mogą mieć różne obudowy => powinno być używane rozróżnianie wielkości liter (jak w moich odpowiedziach). –

1

Ponieważ porównuje te dwie instancje, a nie ich wartość (dwie referencje).

+0

Czy tylko za pomocą właściwości, tj. Właściwości '.FullName' porównywane są wartości zamiast instancji? – baron

+4

W tym przypadku tak. Niektóre klasy implementują interfejs 'IEquatable ' i zastępują 'Object.Equals (Object)' dla operacji równości. "DirectoryInfo" musiałby zaimplementować 'Equals (DirectoryInfo di) {return String.Compare (this.FullName, di.FullName, true) == 0; } 'aby powyższy kod działał (między innymi). Zmieniono porównanie, ponieważ ścieżki mogą mieć inną obudowę. –

4

Zrobiłem Google Search for "równości DirectoryInfo" i znalazłem kilka wspaniałych wyników, w tym jeden na StackOverflow (How to check whether 2 DirectoryInfo objects are pointing to the same directory?)

Jeśli dwa Directory.FullName s mecz, to wiesz, że takie same, ale jeśli nie pasują, wciąż nie wiesz zbyt wiele. Istnieją krótkie nazwy, łącza i skrzyżowania oraz wiele innych powodów, dla których dwa różne ciągi mogą odnosić się do tej samej lokalizacji na dysku.

Jeśli masz pewność, że dwa ciągi nie znajdują się w tym samym miejscu, a bezpieczeństwo jest zagrożone, prawdopodobnie tworzysz błąd bezpieczeństwa. Unikaj uważnie.

+3

Kilka sposobów na "oszukiwanie" DirectoryInfo: komenda 'subst', komenda' net use' lub udział sieciowy. –

2

Jak mówi Jaroslav Jandek (przepraszam nie mogę się wypowiedzieć, nie wystarczy reputacja)

Ponieważ porównuje te dwie instancji, a nie ich wartość (dwa referencje).

Rzeczywiście jest tak samo w przypadku wielu innych przypadków! Ex

IPAddress ip1 = IPAddress.Parse("192.168.0.1"); 
IPAddress ip2 = IPAddress.Parse("192.168.0.1"); 

adresy IP Obie reprezentują ten sam adres, ale trzeba dwa odrębne przypadki klasy IPADDRESS. Więc oczywiście "ip1 == ip2" i "ip1.Equals (ip2)" są fałszywe, ponieważ nie wskazują na ten sam obiekt.

Teraz jeśli zaznaczysz "ip1.Address == ip2.Address" wynik będzie prawdziwy, jak adres IP. Adres jest "długi", więc porównujesz 2 typy wartości. Zauważ, że "ip1.ToString() == ip2.ToString()" będzie również prawdziwe, nawet jeśli ciąg jest typem referencyjnym, a nie typem wartości (ale łańcuchy są naprawdę specjalne).

Tak naprawdę w twoim przypadku chcesz porównać właściwość FullName (to ciąg, więc nie ma problemu).

Mówisz

Czy tylko za pomocą właściwości, to znaczy właściwość .FullName że porównujesz wartość zamiast instancji?

Właściwie ma to więcej wspólnego z tym, czy właściwość jest typem wartości, czy typem odniesienia. Również przy porównywaniu typów odniesienia, w większości przypadków porównanie będzie dotyczyło tego, czy wskazują one na ten sam obiekt, ale możliwe jest przesłonięcie metod lub utworzenie operatorów, tak aby porównanie zostało wykonane na obiektach (ponownie tak jak w przypadku obiektów). Jaroslav Jandek już wskazał).

HTH

+0

Problem ostatecznego ukośnika nadal pozostaje. – SerG

+0

@SerG: rzeczywiście. Bardziej próbowałem wyjaśnić różnicę ByVal vs ByRef niż odpowiedź na konkretne pytanie (i nie myślałem o tym przypadku). – user276648