繁体   English   中英

C#中的静态类列表

[英]List of static classes in C#

我想要一些类,它们都扩展了一个基本抽象类。

然后,我希望有一个对象,每个对象存储这些类的一个子集,并调用它们实现的方法。

所以我想-我对存储的对象不执行任何操作,所以我们只需将这些类设置为静态,就不会浪费存储对象的内存,而只是对静态类的引用,因此可以调用静态函数。 问题是-我该怎么做?

对于那些喜欢代码的人,这是我需要的:

public static abstract class A {
    public static abstract void F();
}

public static class B : A {
    public static override void F() {
        ...
    }
}
// Class Storage of course does NOT work, its just here to illustrate what I need
public class Storage {
    private List<A> list;
    public void AddElement(A element) {
        list.Add(element);
    }
    public void DoStuff() {
        foreach(A element in list)
            element::F();
    }
}

有什么办法可以做这样的事情吗? 或针对此问题的另一种解决方案?

不,你不能那样做。 您尝试执行的操作存在许多问题:

  1. 您不能将静态类型用作类型参数,例如List<A>
  2. 您不能将静态类型用作方法参数,例如AddElement(A element)
  3. 您无法将静态类型抽象化,因为无法从其继承。
  4. 您不能将静态方法抽象化,即使在非静态类中也是如此,因为它不能被覆盖。

从您对问题的描述方式来看,我看不到这里需要静态类型或静态方法。 只需创建一个简单的抽象类并从中继承即可:

public abstract class A {
    public abstract void F();
}


public class B : A {
    public override void F() {
        ...
    }
}

public class Storage {
    private List<A> list;
    public void AddElement(A element) {
        list.Add(element);
    }
    public void DoStuff() {
        foreach(A element in list)
            element.F();
    }
}

另外,您可以创建一个List<Type>并使用反射对那些类型调用静态方法。 例如:

public static class A {
    public static void F() { ... }
}
public static class B {
    public static void F() { ... }
}

List<Type> typeList = new List<Type> { typeof(A), typeof(B) };
foreach(var type in typeList)
{
    type.GetMethod("F").Invoke(null, null); 
}

但是使用反射比使用直接方法调用要慢,并且您将使用此方法失去所有类型安全性(除非您自己编写类型检查)。

pswg的答案显示了处理您提供给我们的代码的正确方法,但是听起来您想做的就是调用方法列表。 这些方法没有关联的数据,因此您考虑将它们设为静态类。 为什么不使用Action?

public class Storage {
    private Action list;
    public void AddElement(Action element) {
        list.Add(element);
    }
    public void DoStuff() {
        foreach(Action element in list)
            element();
    }
}

然后,您可以像这样将方法添加到存储中:

public void DefineStoredFunctions(Storage s)
{
    s.AddElement(() => { first function F });
    s.AddElement(() => { another function F });
    s.AddElement(() => A.F()); //or just call function defined on A
    s.AddElement(B.F); //or get rid of lambda altogether
    //and so on...
}

编辑:如果这不是您要的内容,则应采用其他答案的方法并使用普通对象

这个想法有很多错误:

  • 静态类只有一个实例,只能在“静态上下文”中访问。 您无法定义静态类,然后将其添加为列表的元素。

  • 静态类不能从Object继承,也不能从Object继承(隐式执行)。

  • 由于继承不适用于静态变量,因此虚拟或抽象重写方法的概念也不适用于静态变量。

  • 静态代码只使用稍微少一点的内存,就象普通对象那样使用任何静态实例状态(字段,属性)。

只需使用普通对象即可。 “过早的优化是计算机编程中所有邪恶的根源-无论如何,绝大部分。” 我没有比我正在回答的问题更好地说明该陈述的真实性,在该问题中,非常少的内存节省用于证明试图打破面向对象设计的基本规则(即, 最大限度地减少静态使用) 。

如果要获取对象的实例,请确保您拥有的实例与其他人的实例相同(换句话说,只允许存在一个实例),但仍将其视为对象的实例,请看一下在单例模式 C#中的Singleton可以从其他类继承并可以从其他类继承,可用的实例正是该实例,因此您可以将其传递给其他代码,这些代码不必关心它的来源(例如列表),但是您仍然可以使用静态访问器从不介意的任何地方获取该实例,并且可以强制您只有一个实例。

暂无
暂无

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

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