Статические абстрактные методы в C# (альтернативы для конкретного варианта использования)

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

Я работаю над игрой XNA, но, к счастью, проблема не связана со слишком большим количеством кода XNA. У меня есть абстрактный базовый класс Note и различные производные от него подклассы. В какой-то момент я буду рисовать их на экране, поэтому мне придется загружать текстуры (каждый подкласс будет иметь разные текстуры и разное количество текстур), пользователь вводит параметр размера, масштабирует текстуры по размеру. , а затем перебрать мой List и Draw() каждый. Эти текстуры довольно большие, и каждый экземпляр данного подкласса будет использовать одни и те же текстуры с одинаковым масштабированием до тех пор, пока пользователь не укажет другой размер, отсюда и моя мотивация использовать статический подход.

Как я выяснил, абстрактные статические методы недоступны. Мне бы хотелось иметь возможность изменять размер одной текстуры за раз (всякий раз, когда пользователь изменяет параметр размера) для каждого подкласса, сохранять масштабированную текстуру как статический объект Texture2D и просто ссылаться каждый раз, когда я буду рисовать экземпляр подтип заметки. Таким образом, я мог бы избежать наличия объекта Texture2D в каждом экземпляре данного класса, производного от Note, а также необходимости масштабировать Texture2D в каждом экземпляре. Кроме того, мне бы хотелось иметь возможность эффективно применять «все конкретные подклассы Note должны реализовывать этот статический метод».

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

NoteA.LoadScaledTex(scale);
NoteB.LoadScaledTex(scale);
NoteC.LoadScaledTex(scale);
...
foreach(Note n in notes) {..}

но я не уверен в другом элегантном решении.


person Mark LeMoine    schedule 14.09.2010    source источник


Ответы (2)


Статический на самом деле не подходит просто потому, что данный фрагмент данных должен быть общим для всех экземпляров определенного типа. Скорее (и в этом случае особенно) вы должны использовать синглтон, где все экземпляры внутренне ссылаются на один и тот же единственный экземпляр для хранения общих данных. Таким образом, вы можете легко переопределить реализацию на различных уровнях наследования и даже дать вам возможность использовать некоторые производные типы, даже не используя синглтон.

public abstract class Note
{
    public abstract void LoadScaledTex(scale);
}

public class NoteA : Note
{
    private static ScaledTexData instance;

    public override void LoadScaledTex(scale)
    {
        lock(this.GetType())
        {
            if(instance == null)
            {
                instance = new ScaledTexData(scale);
            }
        }
    }
}
person Rex M    schedule 15.09.2010
comment
Я все еще думаю, что мне придется объявить один из них для каждого подкласса Note (поскольку каждый подтип имеет разное количество текстур). - person Mark LeMoine; 15.09.2010

Вам нужно использовать шаблон проектирования AbstractFactory: http://www.dofactory.com/Patterns/PatternAbstract.aspx

Таким образом, у вас есть NoteAFactory, NoteBFactory, NoteCFactory, производные от NoteFactory, и каждый из них может выполнять разные LoadScaledText.

person Mohamed Nuur    schedule 15.09.2010