2017-07-19 2 views
4

Warum gibt DirectoryInfo.ToString manchmal die FullName (Pfad) und manchmal nur das Verzeichnis Name zurück? Ich bemerkte es nur, weil ich versucht habe, einen Eltern-Verzeichnis-Namen mit dem Verzeichnis-Namen hier verketten:DirectoryInfo.ToString funktioniert in übergeordneten Verzeichnissen anders?

DirectoryInfo dir = new DirectoryInfo(@"C:\Users\Administrator\Desktop\unpack\folder1"); 
DirectoryInfo parentDir = dir.Parent; 
var dirAndParent = $"{parentDir}{Path.DirectorySeparatorChar}{dir.Name}"; 

Zu meiner Überraschung das funktioniert und wieder den gewünschten Teil unpack\folder1. Ich dachte, ich würde parentDir.Name anstelle von parentDir, ähnlich wie dir.Name benötigen. Wenn ich Name von dir.Name entferne, erhalte ich den vollständigen Pfad des Verzeichnisses. Aber die übergeordnete DirectoryInfo Instanz gibt nur die Name zurück.

Wo ist dokumentiert, was ist der Unterschied zwischen beiden DirectoryInfo Instanzen?

Console.WriteLine("dir.ToString: \t\t" + dir.ToString()); 
Console.WriteLine("parentDir.ToString: \t" + parentDir.ToString()); 

Will Ausgang der FullName (Pfad) für dir und die Name für parentDir:

dir.ToString:   C:\Users\Administrator\Desktop\unpack\folder1 
parentDir.ToString:  unpack 

parentDir.FullName kehrt auch der vollständige Pfad: C:\Users\Administrator\Desktop\unpack


Vielleicht ein Fehler, aber sicherlich ein Mangel an Dokumentation. Die Lektion ist klar: Verwenden Sie nie DirectoryInfo.ToString oder übergeben Sie die Instanz in Methoden wie String.Format (oder String-Interpolation), die ToString implizit verwendet, wenn die DirectoryInfo Instanz über DirectoryInfo.Parent initialisiert wurde. Da Sie oft nicht wissen, wie es initialisiert wurde, ist es besser DirectoryInfo.ToString im Allgemeinen zu vermeiden. Dieser Fehler (inkonsistentes, intransparentes Verhalten) könnte in Zukunft behoben werden, wodurch der Code beschädigt würde.

+0

Keine Antwort, aber warum nicht einfach Path.Combine verwenden und die Namen direkt anstelle der String-Verkettung mit dem Pfadtrennzeichen char angeben? Ich denke, Sie könnten sogar andere Ergebnisse erhalten, wenn Parent das Laufwerk root ist - ich könnte mich ärgern, aber ich denke 'new DirectoryInfo (" c: "). ToString()' enthält bereits das Pfadtrennzeichen. Obwohl ich zugeben muss, dass die Ergebnisse, die Sie erfahren, merkwürdig/interessant sind, freue ich mich auf die Antwort von jemandem. Wenn Sie eine 'Refresh()' auf dem Eltern tun, ändert sich die Ausgabe? Kann möglicherweise mit der Zwischenspeicherung und Normalisierung von Dateisystemeinträgen/-namen verwandt werden. – pinkfloydx33

+0

@ pinkfloydx33: Sie haben recht, in diesem Fall wäre 'Path.Combine (parentDir.Name, dir.Name)' 'besser und vermeidet auch dieses Problem, weil Sie eine' DirectoryInfo' -Instanz nicht an 'Path.Combine übergeben können ', du musst explizit sein. Aber es erklärt oder behebt dieses Problem nicht. 'DirectoryInfo.ToString' ist defekt –

Antwort

6

Ich schaute in den Quellcode DirectoryInfo von Microsoft und Sie können dieses Verhalten leicht reproduzieren. Sie verwenden die Internal constructorinternal DirectoryInfo(String fullPath, bool junk), wenn Sie Parent Eigenschaft aufrufen.

Die unten wiedergibt Ihr Problem ohne Parent Aufruf:

var dirInfoUsingPublicConstructor = new DirectoryInfo(@"C:\Test"); 
Console.WriteLine(dirInfoUsingPublicConstructor.ToString()); 

var ctor = typeof(DirectoryInfo).GetConstructors(BindingFlags.NonPublic 
               | BindingFlags.Instance).First(); 
var dirInfoUsingInternalConstructor = 
      ctor.Invoke(new object[] { @"C:\Test", false }) as DirectoryInfo; 
Console.WriteLine(dirInfoUsingInternalConstructor.ToString()); 

Ergebnisse:

C:\Test 
Test 

Intern dass Konstruktor verwendet Path.GetFileName das Ergebnis zu erhalten. Wobei nur der Ordnername zurückgegeben wird. Ich habe keine Ahnung von dem Grund für diese Unterscheidung im Implementierungsdetail. Es könnte ein Fehler sein.

0

an der ToString Definition Blickt man von MSDN es wie ein Aufruf dieser Methode scheint den ursprünglichen Pfad zurückgibt, wurde das in geben.

In Ihrem Anruf

DirectoryInfo dir = new DirectoryInfo(@"C:\Users\Administrator\Desktop\unpack\folder1"); 

Sie in dem vollständigen Pfad geleitet von das Verzeichnis. Wenn Sie mit der Eigenschaft auf den übergeordneten Knoten zugreifen, haben Sie den Konstruktor nicht explizit mit dem vollständigen Pfad aufgerufen. Intern könnte es den relativen Pfad verwendet haben.

Verwandte Themen