.Net Framework 4.7.2

这是一个非常令人惊讶的问题...

我有一个 routine ,可以从本地磁盘获取所有可用的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进行判断,就会得到相同的结果:

templatePaths.Where(Directory.Exists) via QuickWatch dialog

Directory.Exists(templatePaths.First()) via QuickWatch dialog

现在我可以使用重写的版本,但我很好奇我是不是幸运的…:-)

推荐答案

这不是一个好主意.净问题.代码将运行良好,您无需更改任何内容.debugger表示它无法在监视窗口中安全地执行查询,因此无法显示任何结果.这个错误解释了这一点

不支持在此上下文中判断本机方法.

template不是文档列表,而是一个尚未执行的查询.调试器必须执行该查询才能检索结果.

这既不是问题,也不罕见.有几种情况下,调试器无法安全地执行LINQ查询或枚举IEnumerable并显示结果.如果要判断结果,请显式执行查询,例如使用ToList.

PS

使用Glob(3M NuGet下载)这样的globbing库将所有这些代码替换为:

var root = new DirectoryInfo(autodeskPath);
var templates = root.GlobFileSystemInfos("*Inventor*/Templates/**/*.*");

.NET Core本身通过Microsoft.Extensions.FileSystemGlobbing包使用file globbing.

Matcher matcher = new();
matcher.AddIncludePatterns(new[] { "*Inventor*/Templates/**/*.*" });

foreach (string file in matcher.GetResultsInFullPath(autodeskPath))
{
    Console.WriteLine(file);
}

.net相关问答推荐

如何处理以用户为中心的CSP现时值?(uc-lock.bundle.js)

如何手动注入依赖注入

仅使用 .NET GetBytes 方法转换有效字节而不创建问号

为什么(真的吗?)List 实现所有这些接口,而不仅仅是 IList

C#.Net 中的可选返回

无法解析此引用.找不到程序集

.gitignore 和 Visual Studio 项目:忽略 bin/Debug 目录但不忽略 bin/Release 目录

HttpClient 请求抛出 IOException

设置日志(log)文件名以在 Log4j 中包含当前日期

C# 的部分类是糟糕的设计吗?

生产代码中的 System.Diagnostics.Debug.WriteLine

什么是 SUT,它来自哪里?

清除 .NET 的 StringBuilder 内容的最佳方法

.NET 反射的成本是多少?

有没有办法从方法返回匿名类型?

设置 System.Drawing.Color 值

为什么会出现编译错误使用未分配的局部变量?

System.Array.CopyTo() 和 System.Array.Clone() 之间的区别

WPF 中的 Application.DoEvents() 在哪里?

为什么 IList 不支持 AddRange