статический абстрактный класс - PullRequest
8 голосов
/ 13 сентября 2011

Мне нужен способ создать статический класс, в котором некоторые константы могут быть специфическими для конкретного случая, но жестко закодированы.

Что я действительно хочу сделать, так это иметь класс, в котором предусмотрено несколько констант, когда классрасширенный - я хочу жестко закодировать «константы».Я подумал, что сделаю некоторые абстрактные свойства и определю константу get {return;} при расширении класса.

Я знаю, что это невозможно, поэтому теперь я сталкиваюсь с двумя вариантами и задаюсь вопросом, что было бы лучше и почему (если есть варианты, которые я пропускаю, пожалуйста, дайте мне знать!)

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

Полагаю, самым простым способом было бы создать нестатический класс и создать экземпляр, однако я боюсь, что несколько экземпляров этого класса могут быть дорогими, и я хотел бы предотвратить это, если это возможно.

Я не вижу, как я мог бы написать это как шаблон синглтона, не записав его снова в каждом проекте - имея только класс Nested в 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);
    }
}

Первый вариант очень прост и элегантен,что меня беспокоит, так это то, что ничто не заставляет разработчика устанавливать Константу.Я боюсь (по общему признанию маловероятного) сценария, когда неясный угловой случай приведет к тому, что свойство не будет установлено и код не будет работать (и Константа будет последним подозреваемым) ...

Ответы [ 4 ]

6 голосов
/ 13 сентября 2011

Вы можете создавать нестатические классы, которые следуют за синглтоном, гарантируя, что когда-либо существовал только один экземпляр объекта.Я думаю, это может быть следующей лучшей вещью.

5 голосов
/ 13 сентября 2011

Вы не можете хотеть статики и наследования одновременно! Это просто имеет смысл!

Если вам нужно переопределить поведение, вам нужно наследование!

Если вам нужна простота вызова (одно из преимуществ статики), вы можете использовать Factory (или singleton, если нужен только один экземпляр)

Полагаю, вам, вероятно, придется переосмыслить свою модель. Ваш набор констант, вероятно, представляет что-то, что вы можете извлечь в отдельном классе, а затем передать этот класс вашему статическому методу. Будет ли это соответствовать вашим потребностям?

1 голос
/ 13 сентября 2011

Редактировать

К вашему примеру кода:

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

Это помогает?

0 голосов
/ 04 декабря 2015

Мне нужно было примерно то же самое, поэтому сначала я создал нестатический класс со всеми функциями.Затем статический класс, который создает один такой нестатический класс в своем статическом конструкторе.Затем любой из статических методов вызывает соответствующие методы экземпляра.

Примерно так:

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