【发布时间】:2014-09-01 14:59:16
【问题描述】:
我需要根据一个字符串在一组类中找到一个类,我们称之为 ActionString(来自用户输入的 URL,它不等于类名!),创建此类的一个实例并触发一个类方法TriggerSomeAction()。
所以每个 ActionString ("apple", "banana", ...) 应该映射到不同的类。
- 这些类中的每一个都应该派生自一个公共基类(例如 CommonBaseClass)或实现一个公共接口(例如 ICommonInterface)来定义一些公共成员。 1. 这样我就可以通过反射获得所有符合条件的类的列表 2. 将来可以扩展。
- 我希望将 ActionString 作为静态成员存储在这些类中,这样我就可以找到正确的类,而不必先实例化所有类的对象。
这样的代码
var instance = from t in Assembly.GetExecutingAssembly().GetTypes()
where t.GetInterfaces().Contains(typeof(ICommonInterface))
&& t.ActionString = ActionStringEnteredByTheUser
select Activator.CreateInstance(t) as ICommonInterface;
instance.TriggerSomeAction();
或
var instance = from t in Assembly.GetExecutingAssembly().GetTypes()
where t.IsSubclassOf(typeof(CommonBaseClass))
&& t.ActionString = ActionStringEnteredByTheUser
select Activator.CreateInstance(t) as CommonBaseClass;
instance.TriggerSomeAction();
会给我正确的实例并触发某个动作。
我的问题是
- 我希望所有这些类都简单地定义一个我可以比较的 ActionString(最好是常量、静态成员和唯一)。构造一个以 ActionString 为键、类为值的字典会很棒。
目前我发现
- 不可能强制类通过接口实现静态成员,并且
- 接口中的 const 字段已经需要有一个值,并且
-
如果我从抽象类派生类,我可以在这个基类中指定一个静态字段,例如
public abstract class CommonBaseClass { public static string urlActionString; } and override it as class ActionClass : CommonBaseClass { public static new string urlActionString = "apple"; } 但我不知道如何强制派生类覆盖该字段!
- 也研究了一下单例,但不确定这是否是正确的路径
也许我解决这种将动作映射到特定班级的思路是在错误的火车站:)
【问题讨论】:
-
我认为属性,特别是类属性,更适合。因此,您可以使用 ActionString 使用您期望用户提供的一些字符串来注释类。
-
IMO 你走错路了。使用属性或在集中位置手动配置映射。你在追求自动化方面做得太过分了,你最终会得到可能更自动化的代码,但会有非常不受欢迎的属性(首先是“远距离行动”)。