如何实现这个基/派生类结构

本文关键字:派生 结构 何实现 实现 | 更新日期: 2023-09-27 18:09:08

我正在编写一个c#应用程序,它读取X语言的源代码文件,并使用源文件中出现的类,方法等填充数据结构。

之后,使用我刚刚填充的数据结构,我可以调用以下三个函数中的任何一个:

GenerateCS()
GenerateJava()
GenerateCPP()

基本上,它将语言X移植到这三种语言中的任何一种。

我的问题是,我如何构建这样,我有一个类GenerateCode作为一个基类和其他生成函数从它派生?我想每种语言的特定语法细节必须驻留在派生类本身中,但是我可以将什么东西抽象到超类中呢?

如何实现这个基/派生类结构

怎么样:

public enum Language
{
    CS,
    Java,
    CPP
}
public class CS: BaseClass { }
public class Java: BaseClass { }
public class Cpp: BaseClass { }
public class BaseClass
{
    public abstract BaseClass ConvertTo(Language lang);
}

public class BaseClass
{
    public abstract FromClass(BaseClass class, Language lang);
}

我建议您从这样的结构开始:

public class MetaCode
{
    private IList<Fields> fields;
    private IList<Properties> properties;
    private IList<Methods> methods;
    public IList<Fields> Fields
    {
        get { return this.fields; }
    }
    public IList<Properties> Properties
    {
        get { return this.properties; }
    }

    public IList<Methods> Methods
    {
        get { return this.methods; }
    }
    // etc...
}
public interface ISourceReader
{
    MetaCode ReadCode(string sourceCode);
}
public interface ISourceWriter
{
    string WriteCode(MetaCode metaCode);
}
public class CodeConverter
{
    private ISourceReader reader;
    private ISourceWriter writer;
    public CodeConverter(ISourceReader reader, ISourceWriter writer)
    {
        this.reader = reader;
        this.writer = writer;
    }
    public string Convert(string sourceCode)
    {
        MetaCode metaCode = this.reader.ReadCode(sourceCode);
        return this.writer.WriteCode(metaCode);
    }
}

这只是伪代码,但是你可以让你的接口遵循。net框架中经常出现的StreamReader/StreamWriter模式。

接口允许整洁的扩展点,您可以在其中向应用程序添加新的源和目标编程语言。这种方法的最大优点是CodeConverter类对现有的不同编程语言一无所知。新的可以添加或删除,它不需要改变。其他人甚至可以创建新的语言阅读器/编写器并使用它们,而无需触及您的代码/编译程序集。

老实说,考虑到这一点,我认为没有太多的功能可以抽象到一个基类。每种语言的细节都非常具体,以至于很难正确地使用基类。在任何情况下,我总是建议从接口开始,因为这样无论编程语言多么晦涩/不同,您都可以创建实现。

也许你可以创建几个"助手"基类,这些基类包含一些抽象的功能,用于不同的通用编程语言风格:

public abstract class CLikeSourceReader : ISourceReader
{
    public MetaCode ReadCode(string sourceCode)
    {
        // etc..
    }
    // etc..
}
public abstract class VisualBasicLikeSourceReader : ISourceReader
{
    public MetaCode ReadCode(string sourceCode)
    {
        // etc..
    }
    // etc..
}
public abstract class AssemblyLanguageLikeSourceReader : ISourceReader
{
    public MetaCode ReadCode(string sourceCode)
    {
        // etc..
    }
    // etc..
}

这样,在添加新语言时,您可以选择从这些已有的基类之一继承,如果没有合适的接口,可以选择返回到接口。