2010-09-14 1 views
1

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

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

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

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

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

, но я не уверен, что любой другой элегантное решение.

ответ

3

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

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

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

+1

@Mark почему это проблема? –

1

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

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