我有一系列操作。
public class Action {
public string Name { get; set; }
public DoWorkEventHandler DoWork{ get; set; }
}
这是在代码上填充的。
list.Add(new Action("Name", SomeRandomMethod));
...
当有人从该列表中选择一个动作时,它将执行相应的动作。
private void ListBoxSelectionChanged(object sender, SelectionChangedEventArgs e) {
var item = (Action) ListBoxScripts.SelectedItem;
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += item.DoWork;
worker.RunWorkerAsync();
}
但我想从数据库中定义和构建此列表。那么当我从DB获取的是带有方法名称的字符串时,我应该如何用DoWorkEventHandler参数创建一个Action?
答案 0 :(得分:2)
有很多方法可以做到这一点。
您可以声明包含允许调用的所有方法名称的enum
,然后在启动时使用反射构建将enums
映射到methodinfo
的字典。您将枚举存储在数据库中。
另一种选择是装饰类/方法,如下所示:
[ContainsScriptableMethod("MyClassIdentifyingName"] // or a number
class MyUserScriptableMethods
{
[ScriptableMethod("MyMethodIdentifyingName")] // Or just a number as an identifier
void MyMethod()
{
// Do non-malicious stuff.
}
}
当查找一个方法来调用你从数据库中获取一个类ID时,然后使用反射来获取具有正确Id的[ContainsScriptableMethod]
属性的所有类,然后执行相同的查找方法
如果只有少数定义的类具有可以调用/编写脚本的方法,那么您可以拥有该方法的属性。
以下示例代码:
// Enumerate all classes with the ContainsScriptableMethod like so
foreach(var ClassWithAttribute in GetTypesWithAttribute(Assembly.GetExecutingAssembly(), typeof(ContainsScriptableMethodAttribute))
{
// Loop through each method in the class with the attribute
foreach(var MethodWithAttribute in GetMethodsWithAttribute(ClassWithAttribute, ScriptableMethodAttribute))
{
// You now have information about a method that can be called. Use Attribute.GetCustomAttribute to get the ID of this method, then add it to a dictionary, or invoke it directly.
}
}
static IEnumerable<Type> GetTypesWithAttribute(Assembly assembly, Type AttributeType)
{
foreach(Type type in assembly.GetTypes())
{
if (type.GetCustomAttributes(AttributeType, true).Length > 0)
{
yield return type;
}
}
}
static IEnumerable<MethodInfo> GetMethodsWithAttribute(Type ClassType, Type AttributeType)
{
foreach(var Method in ClassType.GetMethods())
{
if (Attribute.GetCustomAttribute(AttributeType) != null)
{
yield Method;
}
}
}