- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
Roslyn 编译器和动力学 --> 我正在尝试编译仅在运行时已知的属性。
在 Visual Studio 中编译时代码有效。使用 Roslyn 编译时,动态属性为“未知”。
在这个示例单元测试中,我有一个继承自 DynamicObject 的 MyObject。这些属性由一个简单的键值字典提供。
当以硬编码方式使用“MyObject”时,我可以调用属性 Hello。我实际上可以在编译时使用任何属性。不存在的属性会在运行时出错。 (预期行为)
在传递给 roslyn 编译器的代码中使用“MyObject”时,我无法在我的动态对象上使用任何属性。这里属性“你好”给我错误:
CS1061 - 'MyObject' does not contain a definition for 'Hello' and no accessible extension method 'Hello' accepting a first argument of type 'MyObject' could be found (are you missing a using directive or an assembly reference?)
我错过了什么?
示例单元测试:
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CSharp.RuntimeBinder;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Testing {
[TestClass]
public class FullExampleTest {
[TestMethod]
public void HardCoded() {
var map = new Dictionary<string, string>() {
{ "Hello","Foo"},
{ "World","Bar"}
};
dynamic src = new MyObject(map);
Console.WriteLine(src.Hello);
Assert.AreEqual("Foo Bar", $"{src.Hello} {src.World}");
}
[TestMethod]
public void CompileAtRuntime() {
string code = @"
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Reflection;
using Testing;
namespace MyNamespace{{
public class MyClass{{
public static void MyMethod(MyObject src){{
Console.WriteLine(src.Hello);
}}
}}
}}
";
var ns = Assembly.Load("netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51");
MetadataReference[] references = new MetadataReference[]
{
MetadataReference.CreateFromFile(ns.Location), //netstandard
MetadataReference.CreateFromFile(typeof(Object).Assembly.Location), //mscorlib
MetadataReference.CreateFromFile(typeof(DynamicObject).Assembly.Location), //System.Core
MetadataReference.CreateFromFile(typeof(RuntimeBinderException).Assembly.Location),//Microsoft.CSharp
MetadataReference.CreateFromFile(typeof(Action).Assembly.Location), //System.Runtime
MetadataReference.CreateFromFile(typeof(FullExampleTest).Assembly.Location) // this assembly
};
var comp = CSharpCompilation.Create(
assemblyName: Path.GetRandomFileName(),
syntaxTrees: new[] { CSharpSyntaxTree.ParseText(code) },
references: references,
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
);
using (var ms = new MemoryStream()) {
var result = comp.Emit(ms);
if (!result.Success) {
var failures = result.Diagnostics.Where(diagnostic => diagnostic.IsWarningAsError || diagnostic.Severity == DiagnosticSeverity.Error);
foreach (Diagnostic diagnostic in failures) {
Console.WriteLine($"{diagnostic.Id} - {diagnostic.GetMessage()}");
}
}
Assert.IsTrue(result.Success, "Compilation failure..");
}
}
}
public class MyObject : DynamicObject {
private IDictionary<string, string> _Map;
public MyObject(IDictionary<string, string> map) {
_Map = map;
}
public override bool TryGetMember(GetMemberBinder binder, out object result) {
Contract.Assert(binder != null);
var ret = _Map.TryGetValue(binder.Name, out string value);
result = value;
return ret;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) {
Contract.Assert(binder != null);
var ret = _Map.TryGetValue(binder.Name, out string value);
result = value;
return ret;
}
}
}
最佳答案
您的动态编译代码与静态编译代码不同。在您的动态编译代码中,您已将 src
显式声明为 dynamic
。您的“硬编码”示例试图将 is 视为 MyObject
。如果您的硬编码测试如下所示,您会遇到同样的问题:
var src = new MyObject(map);
Console.WriteLine(src.Hello);
因此,您可以通过将 src
转换为 dynamic
来解决此问题:
public static void MyMethod(MyObject src){
Console.WriteLine(((dynamic)src).Hello);
}
或者首先声明它是动态的:
public static void MyMethod(dynamic src){
Console.WriteLine(src.Hello);
}
关于c# - Roslyn c# CSharpCompilation - 编译动态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58453115/
我想将一个已经存在的 CSharpCompilation 对象包含到一个新的 CSharpCompilation 对象中。类似于 c# 中的项目到项目引用。我目前的解决方案是在新编译中包含第一次编译的
我正在尝试使用 CSharpCompilation 编译程序集其中有一个简单的类,然后我可以在另一个也通过 CSharpCompilation 编译的程序中引用它.我有这个代码: 命名空间编译测试 {
我一直在尝试向服务器应用程序添加命令系统 问题是:不在项目内但 的命令.cs文件它们是在运行时从另一个文件夹编译的,不能包含任何东西。 编译器代码: static CompilerResults Co
我正在使用 CSharpCompilation 类来编译 SyntaxTree,其中根是一个类声明。我向构造函数传递了一个包含我的 using 语句的 CSharpCompilationOptions
首先,我使用 Windows 10 和 visual studio 2019,使用 .net core 3.1我正在使用来自 Nuget Microsoft.Net.Compilers 3.4.0 和
Roslyn 编译器和动力学 --> 我正在尝试编译仅在运行时已知的属性。 在 Visual Studio 中编译时代码有效。使用 Roslyn 编译时,动态属性为“未知”。 在这个示例单元测试中,我
有谁知道在使用 CSharpCompilation 的扩展方法 Emit 发出程序集时是否可以指定框架版本? 我们显然需要以 4.5.1 为目标,否则我们会遇到严重的运行时错误: MissingMet
如何转换: System.Linq.Expression.Expression 进入: Microsoft.CodeAnalysis.CSharp.CSharpCompilation 或进入: Mic
我正在尝试将一些 .net 代码移植到新的 Core 运行时,但我在移植一些即时编译时遇到了麻烦。 继续,它总是要求我提供对 System.Runtime 和 mscorlib 的引用,但不知道如何引
我正在开发一项服务,给定 Swagger 定义的 URL,使用 NSwag 为该服务生成 C# 代理。整个代理包含在一个 C# 文件中。 我想使用 Roslyn 将生成的代码自动编译为 .NET St
我想创建运行时类,但是当使用 Stimulsoft.Report.Dictionary 中的属性 [StiAlias("id")] 时; 发送错误: [0] = (1,101): 错误 CS0012:
我是一名优秀的程序员,十分优秀!