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";
    }
    
  • 但是我不知道该如何强制派生类覆盖这个字段!

  • 也对辛格尔顿进行了一些调查,但不确定这是否是正确的道路

也许我解决行动到特定类别的映射的思路是在错误的火车站:)

c#如何通过静态成员将字符串映射到公共类集中的类

我认为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();
}