Невозможно преобразовать исходный тип интерфейса в целевой тип интерфейса - PullRequest
2 голосов
/ 14 марта 2012

Я хочу обработать файлы, так как они сохранены в четырех каталогах, все они обрабатываются совершенно по-разному.

У меня есть общий процессор IFileQueueService, который запускается по таймеру диспетчеризации, загружает все имена файлов и вызывает собственный процессор IExecutionProcessor для каждого файла. Это может быть простой вопрос, но у меня есть процессоры с большим количеством свойств, чем у стандартного IExecutionProvider, и я не уверен, как вызывать эти пользовательские процессоры.

//Basic processor interface
public interface IExecutionProvider
{
    void ProcessFile(string file);
}

//Simplified version of one of the custom processor interfaces
public interface IKyoExecutionProcessor
{
    string DestinationPath { get; set; }
}

public class KyoExecutionProcessor : IExecutionProvider, IKyoExecutionProcessor
{
   //This processor moves a file to the DestinationPath.
}

public interface IFileQueueService
{
    string SourcePath { get; set; }
    IExecutionProvider ExecutionProvider { get; set; }
    void Start();
    void Stop();
}

public class FileProcessor : IFileQueueService
{
    ...
    public virtual void ProcessFileQueue()
    {
        IEnumerable<string> filesToProcess = GetFilesReadyToProcess();
        foreach (string file in filesToProcess.ToList())
        {
            ExecutionProvider.ProcessFile(file);
        }
    }
}

public class KYOFileSysWatcher : ServiceBase
{
    private IFileQueueService Processor { get; set; }
    private IKyoExecutionProcessor KyoCustomProcessor { get; set; }

    public KYOFileSysWatcher()
    {
        Processor = ObjectFactory.GetInstance<IFileQueueService>();
        KyoCustomProcessor = ObjectFactory.GetInstance<IKyoExecutionProcessor>();

        //This doesn't work, cannot convert source type to target type, but it implements the IExecutionProvider interface??? How do I do this?
        Processor.ExecutionProvider = KyoCustomProcessor;

        Processor.Start(); //Sets up dispatch timer
    }

 }

Ответы [ 2 ]

1 голос
/ 14 марта 2012

Дженерики на помощь ...

//Basic processor interface
public interface IExecutionProvider
{
    void ProcessFile(string file);
}

//Simplified version of one of the custom processor interfaces
public interface IKyoExecutionProcessor
{
    string DestinationPath { get; set; }
}

public interface IFileQueueService<TProvider>
    where TProvider : IExecutionProvider
{
    string SourcePath { get; set; }
    TProvider ExecutionProvider { get; set; }
    void Start();
    void Stop();
}

public class FileProcessor<TProvider> : IFileQueueService<TProvider>
    where TProvider : IExecutionProvider
{
    string[] GetFilesReadyToProcess() { return new string[0]; }
    public TProvider ExecutionProvider { get; set; }

    public virtual void ProcessFileQueue()
    {
        IEnumerable<string> filesToProcess = GetFilesReadyToProcess();
        foreach (string file in filesToProcess.ToList())
        {
            ExecutionProvider.ProcessFile(file);
        }
    }

    #region IFileQueueService<TProvider> Members

    public string SourcePath { get; set; }
    public void Start() { }
    public void Stop() { }

    #endregion
}

public class KyoExecutionProcessor : IExecutionProvider, IKyoExecutionProcessor
{
    //This processor moves a file to the DestinationPath.
    public string DestinationPath { get; set; }
    public void ProcessFile(string file) { }
}

public class ServiceBase<TProcessor>
    where TProcessor : IExecutionProvider
{
    protected FileProcessor<TProcessor> Processor { get; set; }
    protected TProcessor CustomProcessor { get; set; }
}

public class KYOFileSysWatcher : ServiceBase<KyoExecutionProcessor>
{
    public KYOFileSysWatcher()
    {
        Processor = ObjectFactory.GetInstance<FileProcessor<KyoExecutionProcessor>>();
        CustomProcessor = ObjectFactory.GetInstance<KyoExecutionProcessor>();

        //This compiles now!
        Processor.ExecutionProvider = CustomProcessor;

        Processor.Start(); //Sets up dispatch timer
    }
}
1 голос
/ 14 марта 2012

Ваш IKyoExecutionProcessor интерфейс должен происходить от IExecutionProvider следующим образом:

public interface IKyoExecutionProcessor : IExecutionProvider 
{
    string DestinationPath { get; set; }
}

Это гарантирует, что между интерфейсами существует отношение «есть», что также позволит вам реализовать KyoExecutionProcessor класс, подобный следующему:

public class KyoExecutionProcessor : IKyoExecutionProcessor
{
   public void ProcessFile(string file) { ... }
   public string DestinationPath { get; set; }
}

Таким образом, любой объект, который реализует IKyoExecutionProcessor, может быть назначен переменной типа IExecutionProvider.

Processor.ExecutionProvider = KyoCustomProcessor; // You can now appoint IKyoExecutionProcessor instance to IExecutionProvider variable
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...