Как отключить определенное предупреждение компилятора для определенного файла

Фон

Я работаю над небольшим проектом кодирования, который будет продаваться другим компаниям. Мне нужно было создать для него документацию, поэтому я решил использовать Sandcastle. После долгой загрузки и установки я, наконец, получил его работу и заметил, что какой-либо публичный метод или класс, у которого не было комментариев, имел красный текст, в котором говорилось, что комментарий отсутствует. Затем я установил Ghostdoc, чтобы ускорить мой комментарий. Это включало предупреждения компилятора о отсутствующих комментариях xml, что было здорово, потому что теперь у меня был список всего, что мне нужно было прокомментировать.

Проблема

Один из моих файлов кода - это автоматически сгенерированный файл, содержащий около 3000 предупреждений компилятора. Мне нужно пропустить этот файл из создания предупреждений компилятора "Missing Xml Comment". Я знаю эти вещи из этого сообщения:

  • Я знаю, что могу отключить предупреждение компилятора для проекта, но есть другие файлы в проекте, которые должны иметь предупреждение о компиляторе.
  • Я знаю, что могу использовать #pragma warning disable 1591, чтобы удалить предупреждение компилятора, но файл автогенерируется, и я действительно не хочу, чтобы его повторно добавлять вручную каждый раз.
  • Я знаю, что могу добавить пустой комментарий, но еще раз, я действительно не хочу повторно добавлять его каждый раз, когда файл восстанавливается.
  • Я мог бы вытащить файл в свой собственный проект, поскольку он является единственным классом в нем, а затем удаляет требование комментариев XML, но я не хочу, чтобы клиент имел дело с другой dll.
  • Классы - это частичные классы, поэтому я думал о том, чтобы попытаться найти способ отключения предупреждения #pragma в частичном классе, но даже если это было возможно, все еще есть перечисления, которые выдавали бы предупреждения.

Как я могу заставить VS игнорировать один файл для определенного типа предупреждения?

Ответ 1

Изменить: Мое решение

Я использовал предложение Дэвида Тилена и создал программу на С#, которая вставляет #pragma warning disable сообщения в мои автогенерированные файлы. В идеале я бы назвал это пост-операцией для генерации самих файлов, но на данный момент команда предварительного компиляции будет достаточной, так как мой оператор будет одной из первых строк в файле, ему нужно будет только прочитать несколько строки, см., что оператор disable уже существует и завершает работу, поэтому он не должен замедлять сборку. Ниже приведена моя программа для всех, чтобы наслаждаться!:)

/// <summary>
/// Addes #pragma warning disable messages to source code as part of a prebuild to ignore warnings.
/// Primarly used for autogenerated classes that may contain some compiler warnings by default
/// </summary>
public class Program
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="args">
    /// [0] - file to edit
    /// [1] - line number to insert / edit warning disable at
    /// [2+] - warnings numbers to disable</param>
    static void Main(string[] args)
    {
        // Preconditions
        if (args.Length < 2)
        {
            throw new ArgumentException(String.Format("Unexpected number of parameters.{0}Parameters should be [0] - file to edit{0}[1] - line number to insert / edit warning disable at{0}[2+] - warnings numbers to disable", Environment.NewLine));
        }
        else if (args.Length == 2) { return; }

        // Valid number of args, validate arguments
        string filePath = args[0];
        long lineNumber;

        if(!long.TryParse(args[1], out lineNumber)){
            throw new InvalidCastException("Unable to cast \"" + args[1] + "\" to a long");
        }

        string[] compilerWarningNumbers = new string[args.Length - 2];
        Array.ConstrainedCopy(args, 2, compilerWarningNumbers, 0, compilerWarningNumbers.Length);

        // File Name and line number are valid, perform search and replace
        AddOrUpdateCompilerWarningDisabler(filePath, lineNumber, String.Join(",", compilerWarningNumbers));

    }

    private const string TEMP_FILE_POSTFIX = ".CompilerWarningDisabler.txt";
    public static void AddOrUpdateCompilerWarningDisabler(string filePath, long lineNumber, string compilerWarningNumberCSV)
    {
        if (!File.Exists(filePath))
        {
            throw new FileNotFoundException("File path not found!", filePath);
        }

        // Set Clear Readonly Flag
        FileInfo fileInfo = new FileInfo(filePath);
        bool isReadOnly = fileInfo.IsReadOnly;

        // Get Temp File Name and Delete if it already exists
        string tempFile = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + TEMP_FILE_POSTFIX);
        File.Delete(tempFile);

        // Read from the target file and write to a new file.
        int currentLine = 1;
        string line;
        string textToWrite = "#pragma warning disable " + compilerWarningNumberCSV;
        try
        {
            using (StreamReader reader = new StreamReader(filePath))
            using (StreamWriter writer = new StreamWriter(tempFile))
            {
                while ((line = reader.ReadLine()) != null)
                {
                    if (currentLine == lineNumber)
                    {
                        if (line.StartsWith("#pragma warning disable"))
                        {
                            if (line == textToWrite)
                            {
                                // Nothing has changed, don't bother copying file
                                return;
                            }
                            else
                            {
                                line = textToWrite;
                            }
                        }
                        else
                        {
                            writer.WriteLine(textToWrite);
                            writer.WriteLine(line);
                        }
                    }
                    else
                    {
                        writer.WriteLine(line);
                    }
                    currentLine++;
                }

                if (currentLine == lineNumber)
                {
                    writer.WriteLine(textToWrite);
                }

                if (currentLine < lineNumber)
                {
                    throw new InvalidDataException("File " + filePath + " does not contain line number " + lineNumber);
                }
            }

            // This could potentially delete the source file, but this should be messing with autogenerated files, so even if it does happen, it shouldn't be to hard to get it back
            if (isReadOnly)
            {
                fileInfo.IsReadOnly = false;
            }
            File.Delete(filePath);
            File.Move(tempFile, filePath);
            if (isReadOnly)
            {
                new FileInfo(filePath).IsReadOnly = true;
            }
        }
        finally
        {
            File.Delete(tempFile);
        }
    }
}

Ответ 2

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

Если ваш сгенерированный код является ссылкой на веб-службу, у вас есть возможность указать это при создании ссылки (в диалоговом окне "Добавить ссылку на службу", "Дополнительно" → "Уровень доступа" для сгенерированных классов).

В противном случае вы можете попытаться найти способ автоматического изменения уровня доступа типов в сгенерированном коде от общедоступного до внутреннего.

Ответ 3

Несколько возможностей spring:

  • У вас есть другой класс, который импортирует автоматически сгенерированный файл .cs? Класс wrapping имеет прагму и просто импортирует автогенерированный класс.
  • Напишите perl script (или простую программу на С#), которая вызывается как событие сборки после создания файла и перед компиляцией файлов .cs.