有没有办法检查 类 的文件夹,然后自动实例化它们?
Is there a way to check a folder for classes and then instantiate them automatically?
简而言之,我的程序是比较算法。目前,每当我添加或删除某些算法时,我都必须更改代码。我正在使用 C#。
我的想法是只检查目录中的 classes,然后为该目录中的每个对象在列表(或字典)中实例化它,但我还不太了解这些,但现在让我们说列表)。这样我就不必手动添加每个算法,只需通过在所述文件夹中添加或删除它们来添加或删除 classes。
因此,每当我编译我的程序时,它都会经历 src/model/algorithms,获取每个 c# class 文件,然后将 class 的一个实例添加到列表中。
这可能吗,我该怎么做?
首先您需要从您的目录中获取所有文件名:
DirectoryInfo d = new DirectoryInfo(@"PATHHERE");
FileInfo[] Files = d.GetFiles("*.cs"); //Getting cs files
string str = "";
foreach(FileInfo file in Files )
{
//USE THE "file.Name" TO INSTANTIATE THE CLASS (CHECK THE CODE ABOVE)
}
现在,对于每个名称,您都可以使用 Activator.CreateInstance():
myObject = (MyAbstractClass)Activator.CreateInstance("AssemblyName", "TypeName");
或
var type = Type.GetType("MyFullyQualifiedTypeName");
var myObject = (MyAbstractClass)Activator.CreateInstance(type);
据我了解,您正在编写一个必须 运行 一些 "algorithms" 的可执行文件。您的算法作为 classes 实现,存在于可执行程序的程序集中。您不希望对可执行文件必须执行的算法进行硬编码,但希望它们可以自动发现。
然后简单定义一个接口:
public interface IAlgorithm
{
string Name { get; }
void Execute();
}
并让您的算法实现此接口:
public class FooAlgorithm : IAlgorithm
{
public string Name => "Foo";
public void Execute()
{
Console.WriteLine("Fooing the foo");
}
}
public class BarAlgorithm : IAlgorithm
{
public string Name => "Bar";
public void Execute()
{
Console.WriteLine("Barring the bar");
}
}
程序启动后,scan your assembly for types implementing this interface:
var algorithmTypes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => typeof(IAlgorithm).IsAssignableFrom(p))
.ToList();
foreach (var algorithmType in algorithmTypes )
{
var algorithm = (IAlgorithm)Activator.CreateInstance(algorithmType);
Console.WriteLine($"Executing algorithm '{algorithm.Name}'...");
algorithm.Execute();
}
所以你看,这与 class 个文件无关。
简而言之,我的程序是比较算法。目前,每当我添加或删除某些算法时,我都必须更改代码。我正在使用 C#。
我的想法是只检查目录中的 classes,然后为该目录中的每个对象在列表(或字典)中实例化它,但我还不太了解这些,但现在让我们说列表)。这样我就不必手动添加每个算法,只需通过在所述文件夹中添加或删除它们来添加或删除 classes。
因此,每当我编译我的程序时,它都会经历 src/model/algorithms,获取每个 c# class 文件,然后将 class 的一个实例添加到列表中。
这可能吗,我该怎么做?
首先您需要从您的目录中获取所有文件名:
DirectoryInfo d = new DirectoryInfo(@"PATHHERE");
FileInfo[] Files = d.GetFiles("*.cs"); //Getting cs files
string str = "";
foreach(FileInfo file in Files )
{
//USE THE "file.Name" TO INSTANTIATE THE CLASS (CHECK THE CODE ABOVE)
}
现在,对于每个名称,您都可以使用 Activator.CreateInstance():
myObject = (MyAbstractClass)Activator.CreateInstance("AssemblyName", "TypeName");
或
var type = Type.GetType("MyFullyQualifiedTypeName");
var myObject = (MyAbstractClass)Activator.CreateInstance(type);
据我了解,您正在编写一个必须 运行 一些 "algorithms" 的可执行文件。您的算法作为 classes 实现,存在于可执行程序的程序集中。您不希望对可执行文件必须执行的算法进行硬编码,但希望它们可以自动发现。
然后简单定义一个接口:
public interface IAlgorithm
{
string Name { get; }
void Execute();
}
并让您的算法实现此接口:
public class FooAlgorithm : IAlgorithm
{
public string Name => "Foo";
public void Execute()
{
Console.WriteLine("Fooing the foo");
}
}
public class BarAlgorithm : IAlgorithm
{
public string Name => "Bar";
public void Execute()
{
Console.WriteLine("Barring the bar");
}
}
程序启动后,scan your assembly for types implementing this interface:
var algorithmTypes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => typeof(IAlgorithm).IsAssignableFrom(p))
.ToList();
foreach (var algorithmType in algorithmTypes )
{
var algorithm = (IAlgorithm)Activator.CreateInstance(algorithmType);
Console.WriteLine($"Executing algorithm '{algorithm.Name}'...");
algorithm.Execute();
}
所以你看,这与 class 个文件无关。