是否可以在 C# 中提供 IComparer 实现,并以某种方式在运行时将其“编译”到应用程序中

本文关键字:方式 运行时 应用程序 编译 IComparer 是否 实现 | 更新日期: 2023-09-27 18:36:53

大家好,我不确定我想做的事情是否遥不可及,但我会尽力解释它,并非常感谢任何建议/想法,

想象一下我有:-

    public class Attribute{
        object Value;
        **(X1)**IComparer<T> comparer
    }
    public class AttributeValues
    {
        List<Attribute> values;
        SortedList<Attribute> Sort(){
            this uses the comparer defined in **(X1)** to sort the values in the list
        }
    }

这些类允许用户创建用户定义的属性,并选择预定义的排序算法对值进行排序在简单的情况下,我可以使用我在用户选择的源代码中创建和编译的比较器之一来执行 AttributesValues.Sort()。当事先知道比较时,这很好,例如简单的升序字母排序。

但是,在某些情况下需要更多的逻辑,并且事先不知道。例如,字符串"4DFG5ET"可能会编纂需要排序的日期,并且可能还有其他一些具有类似逻辑的属性,依此类推。

如果可能的话,我不想继续编写 IComparer 实现,并且希望有可能以某种方式在运行时在文本框或文件中定义 IComparer 实现,并且它会以某种方式在程序中编译或持久化然后在可用于对属性进行排序的比较中可用。

有人对如何处理这个问题有任何建议吗?

请问您是否希望我澄清一些事情,因为我知道这是一个有点晦涩的问题。

提前非常感谢

亚历克斯

是否可以在 C# 中提供 IComparer 实现,并以某种方式在运行时将其“编译”到应用程序中

当然,有几种不同的技术支持这一点。Reflection.Emit浮现在脑海中,由于.NET框架包含一个编译器,因此您还应该能够发出C#并将其动态编译到然后加载的程序集中。我相信,在新的动态语言领域还有更多选择。

您可以使用CSharpCodeProvider(请参阅此处的文档)将提供的文本编译为 DLL,并使用反射加载生成的类。另外,这个SO问题可能对您有很大帮助

我认为您可以使用MEF来实现:

报价:"托管扩展性框架(MEF)是.NET的组合层,它提高了大型应用程序的灵活性,可维护性和可测试性。MEF可用于第三方插件可扩展性,也可以将松散耦合的类似插件架构的好处带到常规应用程序中。

在我看来,你有两个选择。首先,您可以构建自己的语言,该语言可以解析简单的用户命令,然后以 JIT 方式执行代码。

第二个选项是实际让用户编写 C# 代码并动态编译它。(如前所述,Reflection.Emit 应该满足大多数简单的需求。

编辑第三个选项并不完全是您想要的,但您可以为比较器插件设置一个目录。当应用程序启动时,它可以扫描该目录并加载程序集。使用反射,可以提取实现 IComparer 接口的任何类,然后将它们作为列表提供给用户。(还可以使用自定义属性来定义友好的用户名和说明等)。

在这种情况下,您不需要重新编译整个应用程序,只是为了快速添加一些新的比较器。此外,如果您有超级用户,他们可以使用一些免费的 .NET 代码编辑器快速编写自己的比较器并将它们"安装"到目录中。