"as" 关键字在 TSql100Parser 代码中被认为是混淆的

"as" keyword considered confusing in TSql100Parser code

假设我要解析 sql 语句

SELECT foo, bar, baz FROM myTable WHERE baz = 2 ORDER BY baz ASC, bar DESC

并以编程方式确定其排序依据的列和方向。经过一些谷歌搜索后,这是我想出的:

List<ParseError> Errors;
TSql100Parser parser = new TSql100Parser(true);
TSqlFragment result = parser.Parse(
    new StringReader("SELECT foo, bar, baz FROM myTable WHERE baz = 2 ORDER BY baz ASC, bar DESC"),
    out Errors);
foreach (var ts in (result as TSqlScript).Batches)
{
    foreach (var st in ts.Statements)
    {
        SelectStatement selectStatement = (SelectStatement) st;
        IList<ExpressionWithSortOrder> _list = selectStatement.QueryExpression.OrderByClause.OrderByElements;
        var c0 = _list[0].Expression as ColumnReferenceExpression;
        var c1 = _list[1].Expression as ColumnReferenceExpression;

        Assert.AreEqual("baz", c0.MultiPartIdentifier.Identifiers[0].Value);
        Assert.AreEqual("Ascending", _list[0].SortOrder.ToString());
        Assert.AreEqual("bar", c1.MultiPartIdentifier.Identifiers[0].Value);
        Assert.AreEqual("Descending", _list[1].SortOrder.ToString());
    }
}

这段代码工作正常,但我觉得它很混乱。 "as" 关键字在两个地方对我来说似乎很奇怪。

第一个在第 6 行。TsqlScript 是 TSqlFragment 的子class,所以我想我很幸运能够将它转换为子class.但是第3行Parse方法的return类型的TSqlFragment没有任何有用的属性,只有它的subclass有有用的属性。那么什么样的 API 会公开一个 class 只有在您碰巧知道将其转换为其他东西时才有用的东西?

"as" 的第二个也是更容易混淆的用法是在内部 foreach 中使用。我怎么可能将 ExpressionWithSortOrders 变成 ColumnReferenceExpressions?它们是 classes,不是接口,它们不相互继承。据我所知,它们之间既没有显式转换也没有隐式转换。

更一般地说,如何才能学会与这样的 API 一起工作?我没有在官方 scriptdom 文档中找到任何关于此转换的信息。 Visual Studio 并没有告诉我可以将这些 class 相互转化。

关于"first case":

MSDN 指出您使用的 Parse 方法的重载

Returns a script fragment and a list of errors by using the provided values. (Inherited from TSqlParser.)

所以我想应该足以知道它是 TSqlScript class ;-)

关于 "second case":

    var c0 = _list[0].Expression as ColumnReferenceExpression;
    var c1 = _list[1].Expression as ColumnReferenceExpression;

How is it possible that I've turned ExpressionWithSortOrders into ColumnReferenceExpressions?

但你没有。您将 ExpressionWithSortOrder class 的 Expression 属性 变成了 ColumnReferenceExpression,根据 docs 完全可以,因为 Expression 属于 ScalarExpression 类型,ColumnReferenceExpression 继承自该类型。