我有一个班级(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和复制到输出目录=复制如果更新
现在的主要方法: 它使用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为常规的部分类提供与现有类相同的效果,其中一个类在构建期间编译,另一个类在运行时在相同的程序集中编译
答案 0 :(得分:3)
简短回答:否。
原始程序集已经编译完毕。 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));
这应该有效。
答案 1 :(得分:1)
不,如this answer所示,部分课程是纯粹的语言功能&#34;。在CLR级别,只有一个类。由于罗斯林最终只会发出一个集会,你不能修改&#34;你的班级就是这样。
答案 2 :(得分:0)
事实上,没有像部分类这样的想法。真正的语言功能是部分类定义。
正如您在the documentation上看到的那样:
可以在两个或多个源文件上拆分类或结构,接口或方法的定义。每个源文件都包含类型或方法定义的一部分,并且在编译应用程序时将所有部分组合在一起。