我有这样一门课:
public abstract class MyClass
{
public abstract string abstract id { get; protected set; }
public abstract Dictionary<string, int> values { get; protected set; }
public MyClass() { this.Initialize(); }
void Initialize() { /*...*/ }
}
我创建了这个类的多个重写脚本,我想在开始时初始化它们。
当调用构造函数和initialize方法时,脚本使用一些数据进行初始化,然后将其自身添加到管理器脚本中。
问题是我不想这样做:
public class Manager : MonoBehaviour
{
public void Start()
{
new OverrideOfMyClass_1();
new OverrideOfMyClass_2();
new OverrideOfMyClass_3();
new OverrideOfMyClass_4();
//..
}
}
我将所有这些覆盖脚本存储在某个文件夹中。
因此,我改为使用DirectoryInfo和..从目录中获取所有.cs类型的文件。当我不知道如何获取类类型并实例化它,以便调用构造函数和初始化方法时,我被卡住了。
有没有办法做到这一点?
发布于 2019-09-12 19:14:26
您可以基于您的cs文件构建一个新的程序集,然后通过反射获取类信息/构造函数。这不是微不足道的代码,所以我不会在这里发布所有内容,但作为开始,你应该看看:
string[] sources;
RuntimeCompiler.DynamicAssemblyInfo dynamicAssemblyInfo;
var trees = sources.Select(s => CSharpSyntaxTree.ParseText(s));
OptimizationLevel optimizationLevel = OptimizationLevel.Release;
var compilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, optimizationLevel: optimizationLevel);
var references = ... list of dlls you need to include to compile properly
var compilation = CSharpCompilation.Create(Path.GetRandomFileName(), trees, references, compilationOptions);
using (var ms = new MemoryStream())
{
EmitResult result = compilation.Emit(ms);
if (!result.Success)
{
... display debug
}
ms.Seek(0, SeekOrigin.Begin);
var assembly = Assembly.Load(ms.ToArray());
... call reflection from here to look for your type in the assembly
}
发布于 2019-09-12 21:36:22
从你做以下事情的能力来看:
new OverrideOfMyClass_1();
new OverrideOfMyClass_2();
new OverrideOfMyClass_3();
new OverrideOfMyClass_4();
我假设这些类正在被编译到程序集中,在这种情况下,使用反射来实例化这些类是相对简单的(尽管我注意到您并不热衷于此,所以如果您不喜欢这个解决方案,请不要介意)。
如果你感兴趣的话,这里有一个基于反射的选项(假设使用等):
var absType = typeof(MyClass);
var subTypes = absType.Assembly.GetTypes()
.Where(t => t != absType && absType.IsAssignableFrom(t));
foreach(var type in subTypes)
{
var subObj = Activator.CreateInstance(type) as MyClass;
// Now you have a subObj if you want to do things with a MyClass object
Console.WriteLine(subObj.id);
}
https://stackoverflow.com/questions/57905333
复制相似问题