c#如何通过静态成员将字符串映射到公共类集中的类
本文关键字:集中 映射 何通过 静态成员 字符串 | 更新日期: 2023-09-27 18:20:17
我需要在一组基于字符串的类中找到一个类,让我们调用它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"; }
但是我不知道该如何强制派生类覆盖这个字段!
- 也对辛格尔顿进行了一些调查,但不确定这是否是正确的道路
也许我解决行动到特定类别的映射的思路是在错误的火车站:)
我认为Attribute类是您想要的。简单示例:
MarkerAttribute类:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public sealed class MarkerAttribute : Attribute {
public string UrlAction { get; private set; }
public MarkerAttribute(string urlAction) {
if (string.IsNullOrEmpty(urlAction)) {
throw new ArgumentNullException("urlAction");
}
UrlAction = urlAction;
}
}
一些默认类:
[Marker("apple")]
public class Foo1 {
}
[Marker("banana")]
public class Foo2 {
}
在程序集中创建类型字典的代码:
var typeDictionary =
(from t in Assembly.GetExecutingAssembly().GetTypes()
where t.GetCustomAttributes(typeof(MarkerAttribute), true) != null &&
t.GetCustomAttributes(typeof(MarkerAttribute), true).Length > 0
select new {
Type = t,
Action = ((MarkerAttribute)t.GetCustomAttributes(typeof(MarkerAttribute), true)[0]).UrlAction
}).ToDictionary(k => k.Type, v => v.Action);
关于继承:
// now the typeDictionary will contain { "banana", typeof(Foo3) } entry
public class Foo3 : Foo2 {
}
// now the typeDictionary will contain { "orange", typeof(Foo3) } entry
[Marker("orange")]
public class Foo3 : Foo2 {
}
接口中有一个Enum怎么样。并且在实际的具体类构造函数中。设置特定于该类类型的枚举值。我认为你也可以对任何其他类型的房产这样做。。
不久前我也做过类似的事情,它看起来有点像这样:(我真的不确定那个代码,这可能需要一些编辑)
public static void GetClass<T>(string ActionString) where T : ICommonInterface, new()
{
var c = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsClass && t.BaseType == typeof(ICommonInterface)).First();
FieldInfo de = c.GetType().GetField(ActionString);
var obj = (T)de.GetValue(c);
obj.TriggerSomeAction();
}