简体   繁体   English

C#将静态类放入字典中

[英]C# Put Static Class Inside Dictionary

I was unclear in an earlier question I ask so I will try to be more explicit. 在先前提出的问题中我不清楚,因此我将尝试更加明确。

Is there a way to put a static class inside of a dictionary so that its functions can be called? 有没有一种方法可以将静态类放入字典中,以便可以调用其功能? If this is not possible, what is the best alternative that doesn't involve using instances that you can suggest? 如果这不可能,那么不建议使用实例的最佳替代方法是什么?

Here is how I would like to use it: 这是我想使用它的方式:

static class MyStatic : IInterface
{
    static void Do(){}
}

static class MyStatic2 : IInterface
{
    static void Do(){}
}

class StaticMap
{
    static Dictionary<Type,IInterface.class> dictionary = new Dictionary<Type,IInterface.class>
    {
        {Type.1, MyStatic}
        {Type.2, MyStatic2}
    };
}

// Client Code

class ClientCode
{
    void Start()
    {
        StaticMap.dictionary[Type.1].Do();
    }
}

There are some fundamental reasons why you can't do that directly: 有一些根本原因导致您不能直接这样做:

  • Static method calls are bound at compile-time 静态方法调用在编译时绑定
  • Static calls are not inherited - they are tied to the class that defines them 静态调用不会被继承-它们与定义它们的类相关联
  • There is no implicit base type (and therefore no polymorphism) between static methods, even if the name, inputs, and outputs are all the same 即使名称,输入和输出都相同,静态方法之间也没有隐式基类型(因此也没有多态性)

Since your signature is the same for every static method, you could store a Action in the dictionary instead: 由于每个静态方法的签名都是相同的,因此可以将Action存储在字典中:

static Dictionary<Type,Action> dictionary = new Dictionary<Type,Action>
{
    {Type.1, MyStatic.Do}
    {Type.2, MyStatic2.Do}
};

then you can call the Action directly: 那么您可以直接调用该Action

void Start()
{
    StaticMap.dictionary[Type.1]();
}

It's slightly repetetive because you have to specify the method name in the dictionary as well, but it's type safe. 这有点重复,因为您也必须在字典中指定方法名称,但是它是安全的类型。

A key question is whether you want to call a single method on each type or whether you need to call multiple methods belonging to each type. 一个关键问题是您是否要在每种类型上调用单个方法,还是需要调用属于每种类型的多个方法。

If it's just a single method, then what D Stanley suggested is the answer. 如果仅是一种方法,那么D Stanley的建议就是答案。 If you store a number of Action s, each representing a method with the same signature on a different static class, then you're accomplishing what you said. 如果存储多个Action ,每个Action代表一个方法,但该方法在不同的静态类上具有相同的签名,那么您就可以完成所说的事情。

However that raises a question - why the constraint that each method must belong to a separate static class? 但是,这提出了一个问题-为什么每个方法必须属于一个单独的静态类的约束? This approach would work just as well if some or all of the methods belonged to the same class. 如果某些或所有方法属于同一类,则此方法同样适用。

If you need to call more than one method from each class then an Action no longer works. 如果您需要从每个类中调用多个方法,那么Action将不再起作用。 You'd have to store collections of Action , which a) means class instances, and b) is a lot more complicated than just using interfaces and class instances. 您必须存储Action集合,其中a)意味着类实例,而b)比仅使用接口和类实例要复杂得多。

One way to manage instances is by using a dependency injection container to create class instances for you. 一种管理实例的方法是使用依赖项注入容器为您创建类实例。 Using that approach, you can create non-static classes without having to go through the hassle of explicitly making them singletons. 使用这种方法,您可以创建非静态类,而不必经历显式使它们成为单例的麻烦。 But you can tell the container to only produce one of each and reuse it. 但是您可以告诉容器仅产生一个容器并重复使用它。 For example, using Castle Windsor: 例如,使用温莎城堡:

container.Register(Component.For<ISomeInterface,SomeClass>));

Now every time the container is asked to provide an instance of ISomeInterface it will always provide the same instance of SomeClass . 现在,每次要求容器提供ISomeInterface的实例时,它将始终提供SomeClass的相同实例。

Because the dependency you're looking for varies by type ( Dictionary<Type, Something> ) it sounds like what you're looking for might be related to generics. 因为您要查找的依赖项因类型( Dictionary<Type, Something> )而异,所以听起来像您要查找的依赖项可能与泛型有关。 But it would be necessary to take a step back from the smaller problem and understand a slightly larger picture of what you're trying to accomplish. 但是,有必要从较小的问题中退后一步,并了解您要完成的工作的大致情况。

Instead of having the entire class as static, create a Singleton instance. 而不是将整个类都设为静态,而是创建一个Singleton实例。

public class Foo
{
   public static Foo _Foo;
   public Foo()
   {
      _Foo = this;
   }
}

Then you may add it to your list, and also inherit from Interfaces, etc. 然后,您可以将其添加到列表中,也可以从Interfaces等继承。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM