【问题标题】:static abstract class静态抽象类
【发布时间】:2011-11-15 22:46:57
【问题描述】:

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

我真正想做的是有一个类,在扩展类时提供几个常量 - 我想要硬编码的“常量”。我想我将创建一些抽象属性并定义 get { return constant; } 扩展类时。

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

  1. 创建具有可为空字段的静态类,并在调用静态方法时如果字段为空则引发异常。
  2. 放弃静态类。拥有一个具有抽象属性的非静态类,并在我需要的任何地方创建对象的实例,即使所有功能都是静态的。

我知道这可能是主观的并且取决于具体情况,但是在考虑这个问题时我会绕圈子,并且确实可以使用一些外部输入。再加上我希望可能不会做我想做的事,我只是在想这个错误。

更新:代码:我将尝试编写一些代码来描述我想要完成的工作。 我知道这段代码行不通!

想象一下,抽象类 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 是在一个单独的项目中定义的,该项目需要该功能并且常量是已知的。

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 中只有 Nested 类。这并不妨碍实现者只创建一个普通的类,并且可能会为每个使用该代码的项目重新展开辩论。

更新#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);
    }
}

选项一非常简单和优雅,令我困扰的是没有强制实现者设置常量。我担心一个(不可否认的)场景,一个不起眼的角落案例会导致属性无法设置并且代码失败(并且不断地成为最后一个嫌疑人)......

【问题讨论】:

  • 为什么你认为你需要一个静态类?您所说的“特定于案例,但硬编码”是什么意思?你能发布一个具体的例子吗?
  • 您不能扩展(继承)静态类,那么您的方案到底是什么?一小段代码值一千字。
  • 你能描述一下使用一些示例——可能是不可编译的——代码吗?
  • 我同意 Joachim,改用 Singleton。如果您需要有关 Singleton 的帮助,请查看 Jon Skeet 的 Singleton 文章。
  • 这里没有静态类(甚至是单例 imo)。

标签: c# static derived-class


【解决方案1】:

你可以创建跟随单例的非静态类,确保对象的一个​​实例永远存在。我想这可能是下一个最好的事情。

【讨论】:

  • 我看不出单例在这种情况下有何帮助。问题是关于继承(不是单例的强项)和静态属性。
  • Anne Lagang 的评论:“如果您需要有关 Singleton 的帮助,请查看 Jon Skeet 的 Singleton 文章。”
【解决方案2】:

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

如果你需要重写行为,你需要继承!

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

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

【讨论】:

    【解决方案3】:

    编辑

    到您的代码示例:

    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();返回输入值 * (int) 常量; }
    • @David:我想我还在编辑中。现在检查我的答案。 (你可以在我说int的地方使用int?,如果这样更合适的话)
    • 实际类型不会是 int?。它可能是 byte[],我试图说明的是它可以为 null,这将指示错误。更通用的 Context 选项对我不起作用。请阅读我的问题的底线,了解我为什么不想使用此选项。
    • @David:使用 Context 类而不是 struct。不给它默认构造函数。利润。 或者:在任何地方使用ctx??DefaultContext。利润。
    【解决方案4】:

    我需要几乎相同的东西,所以首先我创建了一个具有所有功能的非静态类。 然后,一个静态类在其静态构造函数中实例化一个这样的非静态类。 然后任何静态方法调用各自的实例方法。

    类似这样的:

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

    【讨论】:

      【解决方案5】:

      我觉得这在这里没有意义,静态类默认是密封类,这意味着它是密封的以进行继承。所以请不要考虑将静态与抽象相结合。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-04-07
        • 1970-01-01
        • 1970-01-01
        • 2012-12-03
        • 2011-09-26
        • 1970-01-01
        • 2012-10-01
        • 2011-04-02
        相关资源
        最近更新 更多