【问题标题】:Same Code in Multiple Classes without Inheritence没有继承的多个类中的相同代码
【发布时间】:2017-02-01 17:29:49
【问题描述】:

我在 Visual Studio 2015 中使用 AnTLR 的 C# 插件。AnTLR 有一个类 ParserRuleContext,所有解析器规则类都从该类继承。解析器规则类本身被声明为部分类,如下所示:

public partial class SomeRuleContext : ParserRuleContext {
    /* stuff goes here */
}

ParserRuleContext 的定义如下:

public class ParserRuleContext : RuleContext
{
}

我正在为所有解析器规则实现我自己的部分类,以使用解析器树执行自定义操作。我希望能够将属性添加到ParserRuleContext(以及稍后的其他属性/字段/方法),但ParserRuleContext 未声明为partial。由于规则类都已经从另一个类继承,我不能让它们的部分实现也从一个类继承。扩展方法无法获得我想要的所有功能(无法添加属性/字段),而接口让我将完全相同的代码复制/粘贴到每个类中。作为一名软件开发人员,最后一部分几乎让我感到恶心。

我考虑过添加一个指向包含我想要的功能的对象的单个常量属性的想法,但是该解决方案对我来说感觉很笨拙,并且会为该类型的任何成员添加额外的调用。所以这个:

SomeRuleContextInstance.CustomProperty = new FileInfo( "path" );

变成这样:

SomeRuleContextInstance.CommonFunctionality.CustomProperty = new FileInfo( "path" );

我希望有更好的解决方案。

谁能提供一种方法来修改ParserRuleContext 基类或不让我到处复制/粘贴代码?这可以用反射来完成吗?

【问题讨论】:

    标签: c# inheritance antlr4


    【解决方案1】:

    您可以在具体上下文类和ParserRuleContext 之间添加额外的继承级别。

    只需创建一个继承ParserRuleContext的类:

    public abstract class MyParserRuleContext : ParserRuleContext
    {
        // Whatever you want here
    }
    

    然后通过以下选项告诉您的语法使用它:

    grammar MyGrammar;
    
    options {
         contextSuperClass = MyParserRuleContext;
    }
    
    // ...
    

    【讨论】:

    • 我发现了两个注释:A)我需要 MyParserRuleContext 类位于不同的命名空间中,并且 B)您不能使用 Java 目标从命令行运行语法来获得解析树的可视化(obv ......我现在 haz facepalm)。通过设置options=Namespace.Names.MoreNames.MyParserRuleContext 解决了命名空间问题。否则,这是完美的。谢谢! (所有语法选项都可以找到here)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多