How to disable a particular compiler warning for a particular file

后端 未结 3 1325
时光取名叫无心
时光取名叫无心 2021-01-17 09:16

Background

I\'m working on a small coding project that is going to be sold to other companies. I needed to create some documentation for it, so I decided to use S

相关标签:
3条回答
  • 2021-01-17 10:03

    A couple of possibilities spring to mind:

    1. Can you have another class that imports the auto-generated .cs file? The wrapping class has the pragma and just imports the autogenerated class.
    2. Write a perl script (or simple C# program) that is called as a build event after the file is generated and before the .cs files are compiled.
    0 讨论(0)
  • 2021-01-17 10:12

    Edit: My Solution

    I used David Thielen's suggestion and created a C# program that inserts #pragma warning disable messages into my autogenerated files. Ideally I'd call it as a post operation to the generation of the files themselves, but for now a pre-compile command will suffice since my statement will be one of the first lines in the file, it will only have to read a few lines, see that the disable statement is already there, and quit, so it shouldn't slow down the build. Below is my program for all to enjoy! :)

    /// <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);
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-17 10:14

    If the generated classes should not be visible to your users, you could check if the generation tool has an option to generate the classes as internal rather than public.

    If your generated code is a web service reference, you have an option to specify this when you create the reference (in the "Add Service Reference" dialog, Advanced -> Access level for generated classes).

    Otherwise, you could try to find a way to change automatically the access level of the types in the generated code from public to internal.

    0 讨论(0)
提交回复
热议问题