C#中静态类的列表

本文关键字:列表 静态类 | 更新日期: 2023-09-27 18:25:45

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

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

所以我想-我对我存储的对象什么都不做,所以让我们把这些类设为静态的,我不会在存储对象上浪费内存,只是引用静态类,这样我就可以调用静态函数了。问题是——我该怎么做?

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

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

有什么办法做这样的事吗?还是用不同的方法来解决这个问题?

C#中静态类的列表

不,你不能那样做。你试图做的事情有很多问题:

  1. 不能将静态类型用作类型参数—例如CCD_ 1
  2. 不能将静态类型用作方法参数—例如CCD_ 2
  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); 
}

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

p.s.w.g.的答案显示了处理您给我们的代码的正确方法,但听起来您想要做的是调用一系列方法。这些方法没有关联的数据,所以您想让它们成为静态类。为什么不使用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以外的任何对象继承(它隐式继承)。

  • 因为继承不适用于statics,所以虚拟或抽象重写方法的概念也不适用于静力学。

  • Statics只会像普通对象一样,为代码和任何静态实例状态(字段、属性)使用稍少的内存。

只需使用普通对象。"在计算机编程中,过早的优化是万恶之源——不管怎么说,大多数都是如此"。关于这句话的真实性,我想不出比我正在回答的问题更好的例子了,在这个问题中,极少量的内存节省被用来证明试图打破面向对象设计的基本规则是合理的(即最小化对静态的使用)。

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