Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我可以使用roslyn和新的.net项目格式在构建时创建类吗?_C#_.net_Asp.net Core_Roslyn_.net Core - Fatal编程技术网

C# 我可以使用roslyn和新的.net项目格式在构建时创建类吗?

C# 我可以使用roslyn和新的.net项目格式在构建时创建类吗?,c#,.net,asp.net-core,roslyn,.net-core,C#,.net,Asp.net Core,Roslyn,.net Core,我有一个项目使用了新的.net项目格式(dnx和project.json,目前正在mono-1.0.0-beta4上使用dnvm,最终希望在获得dnu restore在*NIX上工作后使用coreclr) 我在.net/C中遇到的一个常见问题是希望在编译时创建代码。例如,我有一个虚拟机,它有一个助手类,如下所示: public static class OpCodes { private readonly static IDictionary<byte, OpCode> _o

我有一个项目使用了新的.net项目格式(
dnx
project.json
,目前正在mono-1.0.0-beta4上使用
dnvm
,最终希望在获得
dnu restore
在*NIX上工作后使用coreclr)

我在.net/C中遇到的一个常见问题是希望在编译时创建代码。例如,我有一个虚拟机,它有一个助手类,如下所示:

public static class OpCodes {
    private readonly static IDictionary<byte, OpCode> _opcodes;

    public static OpCode MOV { get; private set; }
    public static OpCode ADD { get; private set; }
    public static OpCode SUB { get; private set; }

    static OpCodes() {
        // OpCode class contains info, e.g., the number of arguments
        MOV = new OpCode(0x00, "MOV", 2);
        ADD = new OpCode(0x01, "ADD", 0);
        SUB = new OpCode(0x02, "SUB", 0);

        _opcodes = new Dictionary<byte, OpCode> {
            { MOV.Code, MOV },
            { ADD.Code, ADD },
            { SUB.Code, SUB },
        };
    }

    public static OpCode Get(byte code) {
        OpCode result;
        if(_opcodes.TryGetValue(code, out result)) {
            return result;
        }
        return null;
    }
}
公共静态类操作码{
专用只读静态IDictionary操作码;
公共静态操作码MOV{get;private set;}
公共静态操作码添加{get;private set;}
公共静态操作码子{get;private set;}
静态操作码(){
//操作码类包含信息,例如参数的数量
MOV=新操作码(0x00,“MOV”,2);
添加=新操作码(0x01,“添加”,0);
SUB=新操作码(0x02,“SUB”,0);
_操作码=新字典{
{MOV.Code,MOV},
{ADD.Code,ADD},
{SUB.代码,SUB},
};
}
公共静态操作码Get(字节码){
操作码结果;
if(_操作码.TryGetValue(代码,输出结果)){
返回结果;
}
返回null;
}
}
如你所见,那里有很多管道:

  • 操作码列表
  • 每个操作码的静态Getter
  • 一种通过二进制值查找操作码的方法
  • 我唯一需要创建的是#1,它是应用程序的实际内容。我应该把它包装在字典中,创建静态getter

    我知道“常规”VisualStudio有T4模板,但在构建时运行这些模板很麻烦,而且似乎与VisualStudio绑定,因此不再适用

    有什么我能做的吗?我想我可以在project.json中创建自定义操作(例如,
    dnx.regenopcodes
    ),但我不知道我将在这里运行什么,因为我需要调用Roslyn,找到操作码列表(可能制作一个抽象的
    OpCodesBase
    类),解析它,并为我生成具体的
    OpCodes


    或者,我可以创建一个opcodes.xml文件,并使用普通的文本解析从中创建一个.cs,但我不确定在执行
    dnx时如何配置它。运行
    它首先运行我的生成器,然后执行它正常执行的任何操作。

    您可以添加预编译步骤,类似于Razor对预编译视图所做的操作:

    下面是另一个例子:


    这就是你连接它的方式

    但是那些需要的操作码是在哪里指定的?@Tigran只要最容易将它们放入构建中:)例如,
    内部抽象类OpCodeDefs{private readonly OpCode[]OpCode=new[]{new OpCode(0x00,“MOV”,2)}
    或者在一个外部文件(
    OpCode.xml
    )或者实际上,任何为了构建而工作的东西。应用程序代码将专门使用生成的类,并且永远不需要知道源代码。因此
    Dyamic
    不是一个选项(通过解析“源代码”构造真实对象),因为您需要类型安全性。正确的?换句话说,你必须有
    静态
    方法。@Tigran-Hmmm。。。说得好。动态可以工作,但这意味着放弃IntelliSense和运行时惩罚(过早优化警报)。当然,这是一种选择。如果你正朝着代码生成的方向发展,那么无论如何你都会失去智能感知。但是在代码生成的情况下,您可能会从编译时类型检查中受益,这一点不容低估,当我们仍然处于静态类型语言的舒适边界(如
    C.
    )时,忽略它也有点遗憾。谢谢,这样做了!目前,包仍然在主NuGet提要中被调用.Interfaces,但我假设它们将被重命名为.Abstractions soon-ish。这个答案仍然相关吗?看起来
    ICompileModule
    已经消失了。不再是了<代码>ICompileModule
    成功了如何在运行时通过语法生成器使用生成的c#类通过roslyn将它们转储到dll中?