静态抽象类

时间:2011-09-13 08:00:00

标签: c# static derived-class

我需要一种方法来创建一个静态类,其中一些常量可以是特定于案例的,但是是硬编码的。

我真正想做的是有一个类,当类扩展时提供了几个常量 - 我希望'常量'是硬编码的。我想我将制作一些抽象属性并定义get {return constant;扩展课时。

我知道这是不可能的,所以现在我面临两个选择,我想知道什么是最好的和为什么(如果有我缺少的选项,请告诉我!)

  1. 创建一个具有可空字段的静态类,如果在调用静态方法时字段为空,则抛出异常。
  2. 放弃静态类。有一个带有抽象属性的非静态类,并在我需要的地方创建一个对象实例,即使所有功能都是静态的。
  3. 我知道这可能是主观的,并且取决于案例,但是当我考虑这个问题时我会绕圈子,并且可以通过一些外部输入来实现。加上我希望可能没有做我想做的事情,而我只是在考虑这个错误。

    更新:代码:我将尝试编写一些描述我想要完成的代码。 我知道此代码无效!

    想象一下,抽象类Calculation在一个dll中,被许多项目使用。所有这些功能都是相同的,只是常量因项目而异。

    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在一个单独的项目中定义,其中需要功能并且Constant已知。

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

    选项一非常简单和优雅,令我困扰的是,没有任何强制实现者设置常量。我担心一个(不可否认的)场景,一个不起眼的角落案件会导致财产没有被设置,而且代码也会失败(并且Constant是最后一个嫌疑人)......

5 个答案:

答案 0 :(得分:6)

您可以创建遵循singleton的非静态类,确保只有一个对象实例存在。我想这可能是下一个最好的事情。

答案 1 :(得分:5)

你不能同时想要静态和继承!它确实很有感觉!

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

如果你想要简单的调用(静态的一个优点),你可以使用Factory(如果只需要一个实例,则使用单例)

我的猜测是你可能需要重新考虑你的模型。你的这组常量可能代表你可以在一个单独的类中提取的东西,然后将这个类传递给你的静态方法。这符合您的需求吗?

答案 2 :(得分: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;
      }
}

这有帮助吗?

答案 3 :(得分: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);
    }
}

答案 4 :(得分:0)

我觉得这在这里没有意义,静态类默认是密封类,这意味着它是为了继承而密封的。所以请不要考虑静态和抽象。

你可以有一个抽象类,子类可以继承和覆盖方法。