我有一个类(HelloWorld.cs):
public partial class HelloWorld
{
public void SayHello()
{
var message = "Hello, World!";
var length = message.Length;
Console.WriteLine("{1} {0}", message, length);
}
}
上面的类属性BuildAction = Compile。
我在单独的文件中还有另一个类(HelloWorldExtend.cs):
public partial class HelloWorld
{
public void SayHelloExtend()
{
var message = "Hello, World Extended!";
var length = message.Length;
Console.WriteLine("{1} {0}", message, length);
}
}
但是该类的属性是:BuildAction = None 和 Copy to output directory = Copy if newer
现在主要方法: 它使用 Roslyn。
static void Main(string[] args)
{
var code = File.ReadAllText("HelloWorldExtend.cs");
var tree = SyntaxFactory.ParseSyntaxTree(code);
var compilation = CreateCompilation(tree);
var model = compilation.GetSemanticModel(tree);
ExecuteCode(compilation);
Console.ReadLine();
}
private static void ExecuteCode(CSharpCompilation compilation)
{
using (var stream = new MemoryStream())
{
compilation.Emit(stream);
var assembly = Assembly.Load(stream.GetBuffer());
var type = assembly.GetType("HelloWorld");
var greeter = Activator.CreateInstance(type);
var methodextend = type.GetMethod("SayHelloExtend");
methodextend.Invoke(HelloWorld, null);
//Works perfect
var method = type.GetMethod("SayHello");
method.Invoke(greeter, null);
//method is returned null and gives an error : {"Object reference
not set to an instance of an object."}
}
}
是否可以使用 roslyn 为现有类提供与常规分部类相同的效果,其中一个类在构建期间编译,另一个类在运行时在同一程序集中编译 .
最佳答案
简短回答:不。
原始程序集已经编译完毕。 HelloWorld
的类定义已转换为 IL,并且在编译时没有其他源文件来构成分部类的其他部分。
您可以通过将部分文件的两个部分作为源提供来创建一个包含其自己版本的 HelloWorld
的新程序集。
但是
看起来您可以简单地扩展原始类,并可以选择使当前编译的类成为抽象类。
public abstract class HelloWorldBase
{
public void SayHello()
{
var message = "Hello, World!";
var length = message.Length;
Console.WriteLine("{1} {0}", message, length);
}
}
在类上面设置属性BuildAction = Compile
。
public class HelloWorld : HelloWorldBase
{
public void SayHelloExtend()
{
var message = "Hello, World Extended!";
var length = message.Length;
Console.WriteLine("{1} {0}", message, length);
}
}
compilation.AddReferences(new MetadataFileReference(typeof(HelloWorldBase).Assembly.location));
这应该有效。
关于c# - 使用 Roslyn 创建部分类 - 一个在运行时编译的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32806630/