.Net Framework 4.7.2
这是一个非常令人惊讶的问题......
我有这个例程从本地磁盘获取所有可用的 Inventor 模板,无论它是哪个版本:
private static IEnumerable<string> GetInventorTemplates_FAILS()
{
var publicPath = Environment.GetEnvironmentVariable("PUBLIC");
var autodeskPath = Path.Combine(publicPath, "Documents", "Autodesk");
var inventorPaths = Directory.GetDirectories(autodeskPath, "*Inventor*");
var templatePaths = inventorPaths.Select(path => Path.Combine(path, "Templates"));
var templates = templatePaths.Where(Directory.Exists).SelectMany(path => Directory.GetFiles(path, "*.*", SearchOption.AllDirectories));
// throws error ^^^^^^^^^^^^^^^^
return templates;
}
如果我运行这段代码,我会得到这个错误:
System.Linq.SystemCore_EnumerableDebugView`1[System.String].get_Items() calls into native method Microsoft.Win32.Win32Native.GetFullPathName(char*, int, char*, System.IntPtr). Evaluation of native methods in this context is not supported.
更疯狂的是,如果我重写代码,手动调用 Directory.Exists
并且它有效!!!
private static IEnumerable<string> GetInventorTemplates_WORKS()
{
var publicPath = Environment.GetEnvironmentVariable("PUBLIC");
var autodeskPath = Path.Combine(publicPath, "Documents", "Autodesk");
var inventorPaths = Directory.GetDirectories(autodeskPath, "*Inventor*");
var templatePaths = inventorPaths.Select(path => Path.Combine(path, "Templates"));
foreach (var path in templatePaths)
if (Directory.Exists(path)) // <- no exception!!!
foreach (var template in Directory.GetFiles(path, "*.*", SearchOption.AllDirectories))
yield return template;
}
如果您只是通过 QuickWatch 检查,您会得到相同的结果:
现在我可以使用重写的版本,但我很好奇我是不是幸运者...:-)
最佳答案
这不是 .NET 的问题。代码将运行良好,您无需更改任何内容。 调试器 表示无法在监 window 口中安全地执行查询,因此无法显示任何结果。错误说明
Evaluation of native methods in this context is not supported.
template
不是文档列表,它是尚未执行的查询。调试器必须执行该查询才能检索结果。
这既不是问题也不是罕见的。在多种情况下,调试器无法安全地执行 LINQ 查询或枚举 IEnumerable 并显示结果。如果您想检查结果,请显式执行查询,例如使用 ToList
。
附言
使用类似 Glob 的 globbing 库可能是个好主意(3M NuGet 下载)将所有此代码替换为:
var root = new DirectoryInfo(autodeskPath);
var templates = root.GlobFileSystemInfos("*Inventor*/Templates/**/*.*");
.NET Core 本身使用 file globbing通过Microsoft.Extensions.FileSystemGlobbing包。
Matcher matcher = new();
matcher.AddIncludePatterns(new[] { "*Inventor*/Templates/**/*.*" });
foreach (string file in matcher.GetResultsInFullPath(autodeskPath))
{
Console.WriteLine(file);
}
关于c# - System.IO.Directory.Exists 在 LINQ 语句中失败,但在 foreach 循环中不失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71764267/