静态抽象类

12
我需要一种创建静态类的方法,其中某些常量可以是特定于案例的,但是硬编码了。
我真正想做的是创建一个类,在扩展类时提供几个常量 - 我想要“常量”被硬编码。我想通过定义一些抽象属性,并在扩展类时定义 get { return constant; } 来实现这一点。
我知道这是不可能的,所以现在我面临两个选择,并想知道哪种方式最好,为什么(如果有我忽略的选项,请告诉我!)
1.创建一个带有可为空字段的静态类,并在调用静态方法时如果字段为空则抛出异常。
2.放弃静态类。有一个非静态类具有抽象属性,并在需要时创建对象的实例,尽管所有功能都是静态的。
我知道这可能是主观的和依赖情况的,但是当我考虑这个问题时,我总是困惑不解,希望能得到一些外部输入。此外,我希望可能有一种方法可以实现我的愿望,而我只是想错了。
更新:代码:我将尝试编写一些描述我想要完成的代码。我知道这段代码无法正常工作! 请想像一下,抽象类Calculation位于dll中,由许多项目使用。所有项目的功能都相同,只有Constant因项目而异。
public abstract static class Calculation
{
    private abstract int Constant { get; }    //The constant is unknown at this time

    public static int Calculate(int inputValue)
    {
        return inputValue * Constant;
    }
}

类Calc在一个单独的项目中定义,该项目需要该功能并了解常量。

public static class Calc : Calculation
{
    private override int Constant { get { return 2; }
}

...

static class Program
{
    [STAThread]
    static void Main()
    {
        //At some point:
        int result = Calc.Calculate(6);
    }
}

我认为最简单的方法是创建一个非静态类并创建一个实例,但我担心多个类的实例可能会很昂贵,如果可能的话,我想避免这种情况。

我无法看出如何将其编写为单例模式,而又不在每个项目中重新编写 - 只有dll中的嵌套类。这并不能阻止实现者创建普通类,并且很可能在使用代码的每个项目中重新启动辩论。

更新#2:我所说的第一种选择是:

在dll中的类:

public static class Calculation 
{
    public int? Constant {get; set;}

    public static int Calculate(int inputValue)
    {
        if (Constant == null)
            throw new ArgumentNullException();

        return inputValue * (int)Constant;
    }
}

如何在另一个项目中使用该函数:

static class Program
{
    [STAThread]
    static void Main()
    {
        //At some point:
        Calculation.Constant = 2;
        int result = Calc.Calculate(6);
    }
}

选项一非常简单优雅,但是我担心的是它没有强制实现者设置常量。我担心一个(尽管不太可能的)情况,即一个晦涩的边缘情况将导致属性未被设置,从而导致代码失败(并且常量成为最后一个可疑对象)...


你为什么认为需要一个静态类?而且你所说的“特定情况,但硬编码”是什么意思?你能提供一个具体的例子吗? - svick
你无法扩展(继承)一个静态类,那么你的情况到底是什么?一小段代码胜过千言万语。 - H H
你能用一些示例代码(可能不可编译)来描述吗? - Miserable Variable
1
这里没有静态类的情况(甚至在我看来也不需要单例)。 - MattDavey
@Henk:我认为我可以不同意...请注意,这只是一个示例,我担心实际类可能会变得非常庞大——它在静态构造函数中加载了大量数据。 - David Božjak
显示剩余4条评论
5个回答

6

您可以创建遵循单例模式的非静态类,确保对象只存在一个实例。我想这可能是下一个最好的选择。


1
我不认为单例在这种情况下有帮助。问题是关于继承(而不是单例的强项)和静态属性。 - Sascha Hennig
Anne Lagang的评论:“如果你需要关于Singleton的帮助,请查看Jon Skeet的Singleton文章。” - Daniel Hilgarth

5

您不能同时想要静态和继承!这根本没有意义!

如果您需要覆盖行为,则需要继承!

如果您想要简单的调用(静态的优点之一),则可以使用工厂(或者如果只需要一个实例,则使用单例)

我猜您可能需要重新思考您的模型。您的这组常量可能代表着某个东西,您可以将其提取到一个单独的类中,然后将该类传递给您的静态方法。这样符合您的需求吗?


为什么同时想要静态和继承是没有意义的? - Eli Davis

1

编辑

关于你的代码示例:

public abstract static class Calculation
{
    public static int Constant { get; set; }
    public static int Calculate(int i) { return i * Constant; }
}

// ...

Calculation.Constant = 6;
Calculation.Calculate(123);

稍微更加通用一些:

public abstract static class Calculation
{
    public struct Context
    {
        public int Constant, SignificantDigits;
        public bool Radians;
    }
    public static int Calculate(int i, Context ctx) { return i * ctx.Constant; }
}

// ...
Calculation.Calculate(123, new Calculate.Context { Constant = 6 });

第一个想法:

我能想到的最接近的是泛型:

public interface ISpecifics
{ 
     void DoSomething();
     string SomeProp { get; }
}

public static class Static<S> 
    where S : ISpecifics, new()
{

      public static string ExerciseSpecific()
      {
            var spec = new S();
            spec.DoSomething();
            return spec.SomeProp;
      }
}

或者如果你真的需要一个单一的静态类型

public static class Static
{
      public static string ExerciseSpecific<S>()
          where S : ISpecifics, new()
      {
            var spec = new S();
            spec.DoSomething();
            return spec.SomeProp;
      }
}

这有帮助吗?


对于你的修改:这就是我在原问题中所说的选项1。让属性为int?常量{get; set;},然后在Calculate(int inputValue)中使用{if (Constant == null) throw new NullArgumentException(); return inputValue * (int)Constant;} - David Božjak
@David:我觉得我还在编辑。现在检查一下我的答案。(如果更合适,你可以在我说“int”的地方使用“int?”) - sehe
实际类型可能不是 int,而是 byte[]。我想表达的是它可以为空,这将表示错误。使用 Context 的更一般选项对我来说不可行。请阅读我的问题底部以了解为什么我不想使用此选项。 - David Božjak
@David:使用Context类而不是结构体。不要给它默认构造函数。受益。或者:在任何地方都使用ctx??DefaultContext。受益。 - sehe

0
我觉得这里并不合理,静态类默认是密封类,这意味着它对于继承来说是被密封的。因此,请不要考虑使用带有抽象关键字的静态类。
你可以创建一个抽象类,子类可以继承并重写方法。

0
我需要的基本上是同样的东西,所以我首先创建了一个非静态类,其中包含所有功能。 然后,创建一个静态类,在其静态构造函数中实例化这样一个非静态类。 然后,任何静态方法都调用相应的实例方法。
类似于这样的东西:
public class CalculationInstance
{
    private int constant;

    public int Calculate(int inputValue)
    {
        return inputValue * constant;
    }

    public void AnyOtherMethod()
    {
    ....
    }    

    public CalculationInstance(int constant)
    {
    this.constant=constant;       
    }
}


public static class Calculation 
{
    const int CONSTANT=2;
    private CalculationInstance calc;

    static Calculation()
    {
        calc=new CalculationInstance(CONSTANT);
    }

    public static int Calculate(int inputValue)
    {
        return calc.Calculate(inputValue);
    }

    public static void AnyOtherMethod()
    {
        calc.AnyOtherMethod();
    }    

}

static class Program
{
    [STAThread]
    static void Main()
    {
        //At some point:
        int result = Calculation.Calculate(6);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接