为啥这个 DirectoryInfo 比较不起作用? [复制]
Posted
技术标签:
【中文标题】为啥这个 DirectoryInfo 比较不起作用? [复制]【英文标题】:Why isn't this DirectoryInfo comparison working? [duplicate]为什么这个 DirectoryInfo 比较不起作用? [复制] 【发布时间】:2011-03-10 11:04:41 【问题描述】:可能重复:How to check whether 2 DirectoryInfo objects are pointing to the same directory?
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
在调试时,我可以检查每个值,它们是相等的。所以我猜这是另一个 byval byref 误解......请有人,我如何比较这两件事?
【问题讨论】:
比较 DirectoryInfo 对象的原因是什么?也许你应该比较一下 .FullPath? 这些路径不同。这是某种 Stroop 测试吗? 另外,你的大括号被注释掉了。如果您希望我们投入精力帮助您,您不会投入精力提出一个好问题吗? 【参考方案1】:我相信你想这样做:
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
............
在您的示例中,您正在比较 2 个不同的对象,这就是它们不相等的原因。我相信你需要比较路径所以使用上面的代码。
【讨论】:
请记住,相同的两条路径可以有不同的大小写 => 应该使用不区分大小写的比较(如我的答案中的 cmets)。【参考方案2】:我在 Google 上搜索了“DirectoryInfo 相等性”,发现了几个很好的结果,包括 *** (How to check whether 2 DirectoryInfo objects are pointing to the same directory?) 上的一个结果
如果两个Directory.FullName
s 匹配,那么你知道它们是相同的,但如果它们不匹配,你仍然不知道很多。两个不同的字符串可以引用磁盘上的同一位置,存在短名称、链接和连接以及许多其他原因。
如果您指望确定两个字符串不在同一个位置,并且安全受到威胁,那么您很可能会产生安全漏洞。小心行事。
【讨论】:
“欺骗” DirectoryInfo 的一些方法:subst
命令、net use
命令或网络共享。【参考方案3】:
正如 Jaroslav Jandek 所说(对不起,我无法发表评论,没有足够的声誉)
因为它比较了这两者 实例,而不是它们的值(两个 参考)。
实际上,很多其他情况也是如此!例如
IPAddress ip1 = IPAddress.Parse("192.168.0.1");
IPAddress ip2 = IPAddress.Parse("192.168.0.1");
两个 IP 地址代表相同的地址,但您有 两个不同的实例 IPAddress 类。所以当然 "ip1 == ip2" 和 "ip1.Equals(ip2)" 都是假的,因为它们不指向同一个对象。
现在,如果您检查“ip1.Address == ip2.Address”,结果将为真,因为 IPAddress.Address 是“long”,因此您正在比较 2 种值类型。请注意,“ip1.ToString() == ip2.ToString()” 也将成立,即使字符串是引用类型而不是值类型(但字符串确实很特殊)。
因此,在您的情况下,您确实想比较 FullName 属性(这是一个字符串,所以没问题)。
你说
是否仅通过使用属性,即 .FullName 属性来比较值而不是实例?
其实跟属性是值类型还是引用类型有更多的关系。此外,在比较引用类型时,大多数情况下比较的是它们是否指向同一个对象,但可以覆盖方法或创建运算符,以便在 content 的 content 上进行比较对象(就像 Jaroslav Jandek 已经指出的那样)。
HTH
【讨论】:
最后斜线的问题依然存在。 @SerG:确实。我更想解释 ByVal 与 ByRef 的区别,而不是回答具体问题(我也没有想到这种情况)。【参考方案4】:因为它比较的是这两个实例,而不是它们的值(两个引用)。
【讨论】:
是否仅通过使用属性,即.FullName
属性来比较值而不是实例?
在这种情况下,是的。一些类实现IEquatable<T>
接口并覆盖Object.Equals(Object)
以进行相等操作。 DirectoryInfo
必须实现 Equals(DirectoryInfo di) return String.Compare(this.FullName, di.FullName, true) == 0;
才能使上面的代码工作(除其他外)。更改了比较,因为路径可能有不同的大小写。以上是关于为啥这个 DirectoryInfo 比较不起作用? [复制]的主要内容,如果未能解决你的问题,请参考以下文章