Класс Дизайн C # Кастинг - PullRequest
0 голосов
/ 24 марта 2012

Допустим, у меня есть программа для записи текста в файл (не совсем, но это легче объяснить). Мне нужен отдельный класс для каждого типа файла, такого как PdfType и WordType, который наследуется от FileTypeMaster.

FileTypeMaster (base)
-PdfType : FileTypeMaster
-WordType : FileTypeMaster (same methods as pdftype but works different)

Теперь к реальной проблеме ... Я хочу, чтобы пользователь сам решал, какой тип программы использовать. Если он хочет Pdf ИЛИ Word, метод methodcall должен выглядеть одинаково (потому что слово новое, а программа раньше была только для pdf).

Как это должно работать, например, с pdf:

static FileTypeMaster MyFavoriteType; //declare a general var 
MyFavoriteType = new PdfType(); //cast general var to the wanted type
MyFavoriteType.CompileThis();

Как это должно работать со словом: то же самое, но MyFavoriteType = new WordType (); `

Ответы [ 5 ]

4 голосов
/ 24 марта 2012

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

Вот небольшой пример:

public interface Polygon
{
  float GetArea();
}
public class Square : Polygon
{
  float Side;
  public Square(float side)
  {
    Side = side;
  }
  Polygon.GetArea()
  {
    return side*side;
  } 
}

Теперь вы можете сделать что-то вроде этого:

Polygon MyPolygon = new Square(5f);
float area = MyPolygon.GetArea();

И это будет работать для ЛЮБОГО ОДНОГО КЛАССА, который правильно реализует интерфейс Polygon. Так что это возможно:

Polygon MyPolygon = new Circle(5f);
float area = MyPolygon.GetArea();

В вашем случае интерфейс будет выглядеть так:

public interface MyFavoriteType//or name it FileTypeMaster, since that's what you want to anme it
{
  void CompileThis();
}
1 голос
/ 24 марта 2012

Используйте базовый класс, только если вы разделяете поведение между своими подклассами.Если вы разделяете только сигнатуры и свойства метода (например, каждый подкласс не использует функциональность базового класса), используйте вместо этого интерфейс.

0 голосов
/ 24 марта 2012

Ваш базовый тип может быть классом или интерфейсом. Допустим, это интерфейс:

interface IFileProcessor { void CompileThis(); }
class PdfProcessor : IFileProcessor { public void CompileThis() { /* ... implementation omitted ... */ }
class WordProcessor : IFileProcessor { public void CompileThis() { /* ... implementation omitted ... */ }

Тогда:

private enum ProcessorType
{
    Undefined,
    Word,
    Pdf
}

public void Main(string[] args)
{
    ValidateArgs(args); // implementation omitted
    ProcessorType requestedProcessor = GetRequestedProcessorFromArgs(args); // implementation omitted
    IFileProcessor processor = GetProcessor(requestedProcessor);
    processor.CompileThis();
}

private IFileProcessor GetProcessor(ProcessorType requestedProcessorType)
{
    switch (requestedProcessorType)
    {
        case ProcessorType.Pdf:
            return new PdfProcessor();
        case ProcessorType.Word:
            return new WordProcessor();
        default:
            throw new ArgumentException("requestedProcessorType");
    }
}
0 голосов
/ 24 марта 2012

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

0 голосов
/ 24 марта 2012

Что вы хотите сделать здесь, так это использовать полиморфизм . На самом деле, вы любезно реализуете шаблон проектирования стратегии здесь, где у вас есть базовый класс (или интерфейс)

public abstract class FileTypeMaster
{
    public abstract CompileThis();
}

И имеют разные реализации, для Word и Pdf:

public class PdfType : FileTypeMaster
{
    public override CompileThis () {}
}

Затем в вызывающей программе вы можете создать правильную реализацию:

FileTypeMaster x = new PdfType();
x.CompileThis()

или

FileTypeMaster x = new WordType() x.CompileThis()

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

public abstract class FileTypeMaster
{
    public abstract CompileThis();

    public static FileTypeMaster Create( FileType type )
    {
         switch( type )
         {
             case FileType.Word : return new WordType();

             case FileType.Pdf : return new PdfType();

             default:
                 throw new NotImplementedException();
         }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...