Упрощение логики, чтобы избежать дублирования сообщений об ошибках

Пока у меня есть следующее:

// Gets all the drives 
DriveInfo[] allDrives = DriveInfo.GetDrives();

// checks if any CD-Rom exists in the drives
var cdRomExists = allDrives.Any(x => x.DriveType == DriveType.CDRom);

// Get all the cd roms
var cdRoms = allDrives.Where(x=>x.DriveType==DriveType.CDRom);

if (cdRomExists.Equals(true))
{
    // Loop through the cd roms collection
    foreach(var cdRom in cdRoms)
    {
        Console.WriteLine("Drive {0}", cdRom.Name);
        Console.WriteLine("  File type: {0}", cdRom.DriveType);

        if (cdRom.IsReady == true)
        {
            if (cdRom.DriveType == DriveType.CDRom)
            {
                DirectoryInfo di = new DirectoryInfo(cdRom.RootDirectory.Name);

                var file = di.GetFiles("*.csv", SearchOption.AllDirectories).FirstOrDefault();

                if (file == null)
                {
                    errorwindow.Message = LanguageResources.Resource.File_Not_Found;
                    dialogService.ShowDialog(LanguageResources.Resource.Error, errorWindow);
                }
                else
                {
                    foreach (FileInfo info in di.GetFiles("*.csv", SearchOption.AllDirectories))
                    {
                        Debug.Print(info.FullName);
                        ImportCSV(info.FullName);
                        break;      // only looking for the first one
                    }
                }
            }
        }
        else if (cdRom.IsReady == false)
        {
            errorwindow.Message = LanguageResources.Resource.CDRom_Not_Ready;
            dialogService.ShowDialog(LanguageResources.Resource.Error, errorWindow);              
        }
    }
}
else
{
    errorwindow.Message = LanguageResources.Resource.CDRom_Error;
    dialogService.ShowDialog(LanguageResources.Resource.Error, errorWindow);
}

Проблема со следующим заключается в том, что два раза подряд появляется сообщение об ошибке, указывающее, нет ли в приводе компакт-диска, потому что мой компьютер содержит и дисковод DVD, и привод Blu-ray. Если есть CD Rom, содержащий файл CSV, он успешно импортируется, но появляется другое сообщение из-за цикла foreach, который запускается на диск Blu-ray и всплывает.

Я хочу отображать только одно сообщение об ошибке для каждой из следующих ситуаций: -Если CD Rom не готов и содержит csv в дисководе. Если CD-ROM не содержит csv.

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

3 ответа

Это мой подход к вашей проблеме:

bool anyCdrom = false;
bool anyReady = false;
bool fileFound = false;

// Loop through the cd roms collection
foreach(var cdRom in  DriveInfo.GetDrives().Where(drive => drive.DriveType == DriveType.CDRom))
{
    anyCdrom = true;
    Console.WriteLine("Drive {0}", cdRom.Name);
    Console.WriteLine("  File type: {0}", cdRom.DriveType);   
    if (cdRom.IsReady) // You may want to put in into the intial where
    {
        anyReady = true;        
        foreach (string file in Directory.EnumerateFiles(cdRom.RootDirectory.Name, "*.csv", SearchOption.AllDirectories))
        {
            fileFound = true;
            Debug.Print(file);
            ImportCSV(file);
            break;      // only looking for the first one
        }
        if(fileFound)
            break;                                      
    }       
}

if(!anyCdrom)
{
    errorwindow.Message = LanguageResources.Resource.CDRom_Error;
    dialogService.ShowDialog(LanguageResources.Resource.Error, errorWindow);
}   
else if(!anyReady)
{
    errorwindow.Message = LanguageResources.Resource.CDRom_Not_Ready;
    dialogService.ShowDialog(LanguageResources.Resource.Error, errorWindow);                     
}
else if(!fileFound)
{
    errorwindow.Message = LanguageResources.Resource.File_Not_Found;
    dialogService.ShowDialog(LanguageResources.Resource.Error, errorWindow);
}

Он печатает только ошибку, когда:

  1. нет CDROM
  2. нет готового диска
  3. нет никакого CSV-файла в любом готовом CDROM

Вам просто нужно отслеживать, работал ли хотя бы один из дисков у вас. Если ни один из них не сделал, то вы хотите вывести сообщение об ошибке. Есть также некоторые другие вещи, которые вы могли бы сделать (нет необходимости делать Any/Whereнет необходимости делать .Equals(true)и т. д. И, более конкретно, не нужно постоянно проверять, подходит ли это тип привода. cdRoms Коллекция будет содержать только диски с правильным типом, потому что это то, что вы указываете в своем Where пункт.

// Gets all the drives 
DriveInfo[] allDrives = DriveInfo.GetDrives();

// Get all the cd roms
var cdRoms = allDrives.Where(x=>x.DriveType==DriveType.CDRom);

if (cdRoms.Count() > 0)
{
    bool found = false;
    // Loop through the cd roms collection
    foreach(var cdRom in cdRoms)
    {
        Console.WriteLine("Drive {0}", cdRom.Name);
        Console.WriteLine("  File type: {0}", cdRom.DriveType);

        if (cdRom.IsReady == true)
        {
            DirectoryInfo di = new DirectoryInfo(cdRom.RootDirectory.Name);

            var file = di.GetFiles("*.csv", SearchOption.AllDirectories).FirstOrDefault();

            if (file == null)
            {
                errorwindow.Message = LanguageResources.Resource.File_Not_Found;
                dialogService.ShowDialog(LanguageResources.Resource.Error, errorWindow);
            }
            else
            {
                foreach (FileInfo info in di.GetFiles("*.csv", SearchOption.AllDirectories))
                {
                    Debug.Print(info.FullName);
                    ImportCSV(info.FullName);
                    found = true;
                    break;      // only looking for the first one
                }
            }
        }
        else
        {
            Debug.Print(string.Format("Drive {0} is not ready", cdRom.Name));

        }
    }
    if (!found)
    {
        errorwindow.Message = LanguageResources.Resource.CDRom_Not_Ready;
        dialogService.ShowDialog(LanguageResources.Resource.Error, errorWindow);              
    }
}
else
{
    errorwindow.Message = LanguageResources.Resource.CDRom_Error;
    dialogService.ShowDialog(LanguageResources.Resource.Error, errorWindow);
}

Ваш код может быть переписан следующим образом:

var cdRoms = allDrives.Where(x => x.DriveType == DriveType.CDRom && x.IsReady);

if (cdRoms.Any())
{
    foreach(var cdRom in cdRoms)
    {
        Console.WriteLine("Drive {0}", cdRom.Name);
        Console.WriteLine("  File type: {0}", cdRom.DriveType);

        var di = new DirectoryInfo(cdRom.RootDirectory.Name);
        var file = di.GetFiles("*.csv", SearchOption.AllDirectories).FirstOrDefault();

        if (file == null)
        {
            errorwindow.Message = LanguageResources.Resource.File_Not_Found;
            dialogService.ShowDialog(LanguageResources.Resource.Error, errorWindow);
        }
        else
        {
            foreach (var info in di.GetFiles("*.csv", SearchOption.AllDirectories))
            {
                Debug.Print(info.FullName);
                ImportCSV(info.FullName);
                break;
            }
        }
    }
}
else
{
    errorwindow.Message = LanguageResources.Resource.CDRom_Error;
    dialogService.ShowDialog(LanguageResources.Resource.Error, errorWindow);
}

Изменения:

  • Не нужно использовать Where а также Any Как и вы, отфильтруйте дисководы CD-Rom со всех дисков и посмотрите, существуют ли они
  • Выбирайте только те диски, которые являются приводами CD-Rom и готовы
  • использование var где возможно, пусть компилятор сделает работу
Другие вопросы по тегам