CQLinq 确实提供了许多在命名空间NDepend.Reserved.CQLinq 中定义的便捷扩展方法。这些扩展方法在 CQLinq 编译后时得到特殊处理,并且本身在 C# 中不可用。
在 CQLinq 查询中编写时:t.Implement("System.IDisposable".AllowNoMatch())
...特殊的ExtensionMethodsCQLinqDependency.Implement() 扩展方法已解决。 CQLinq post-C#-compilation/pre-execution 步骤尝试在执行前解析指定为字符串 ("System.IDisposable".AllowNoMatch()) 的类型一次,并在 IType 上推断谓词。
- 如果未找到全名为
"System.IDisposable" 的类型,则始终返回 false。
- 如果找到一个全名为
"System.IDisposable" 的类型,则返回true。对于实现它的类型。
ExtensionMethodsCQLinqDependency.Implement()的文档中规定该方法只能在ICQLinqExecutionContext中调用,否则必须调用NDepend.CodeModel.IType.NDepend.CodeModel.IType.Implement方法。
因此,通过使用 NDepend.API,您必须自己完成 CQLinq 后编译工作,但这非常直接:
var iDisposable = codebase.Types.SingleOrDefault(t.FullName == "System.IDisposable");
if(iDisposable == null) {
return new IType[0];
}
return from t in codeBase.Application.Types
where t.Implement(iDisposable)
select t;
我可以看到有一个 NDepend.CodeQuery 命名空间,其中包含 CreateQuery、Compile 和 Execute 等方法。谁能给我一个用法示例吗?
确实,使用 NDepend.API,您可以编译 CQLinq 查询字符串,执行它并使用结果。 OSS Power Tools 使用 CQLinq 查询代码,$NDependRedistributable$\NDepend.PowerTools\CodeQueryConsole\CodeQueryConsolePowerTool.cs
中提供了一个示例用法
var codeBase = analysisResult.CodeBase;
Func<string, IQueryCompiled> compileQueryProc = queryString => queryString.Compile( codeBase);
// ... but if we can get a compareContext, then compile and execute the query against the compareContext
ICompareContext compareContext;
if (ProjectAnalysisUtils.TryGetCompareContextDefinedByBaseline(analysisResult, out compareContext)) {
Debug.Assert(compareContext != null);
compileQueryProc = queryString => queryString.Compile(compareContext);
}
...
IQueryCompiled queryCompiled;
using (var queryEditSession = new QueryEditSession(queriesPreviouslyEdited)) {
var queryString = queryEditSession.GetQueryString();
COMPILE_QUERY:
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.White;
if (queryString == null) { break; }
// Try compile query
queryCompiled = compileQueryProc(queryString);
var queryCompiledError = queryCompiled.QueryCompiledError;
if (queryCompiledError != null) {
queryString = queryEditSession.ShowCompilatioErrorsAndThenGetQueryString(queryCompiledError);
goto COMPILE_QUERY;
}
}
// Execute query compiled
var queryCompiledSuccess = queryCompiled.QueryCompiledSuccess;
Debug.Assert(queryCompiledSuccess != null);
var result = queryCompiledSuccess.Execute();
if (result.Status != QueryExecutionStatus.Success) {
var exception = result.Exception;
// The error must be an Exception thrown by the query, since we don't use the Execute(...) overload with time-out!
Debug.Assert(exception != null);
DisplayQueryThrowAnException(exception);
continue;
}
QueryExecutionResultDisplayer.Go(result.SuccessResult);
Console.WriteLine();
}