This project is read-only.
1
Vote

Strange C# Compiler Problem

description

First I'm not using rosyln to compile the so I don't know If the error happen also when I use it.
So I could have found some strange think. I'm working on some code for a project that I'm doing but I run into this strange situation. I have the following two classes
interface ILogger
{
 string LoggerName { get; }

        void LogInfo(string message, params object[] @params);

        void LogWarning(string message, params object[] @params);

        void LogDebug(string message, params object[] @params);

        void LogError(string message, params object[] @params);

        void LogType(Type scriptType, string message);
}

 public class GameLogger : ILogger
    {
        private readonly StreamWriter _logFileWriter;
        private static readonly int ErrorLoggerCounter = 0;
        private static int _loggerNumber;

        public string LoggerName
        {
            get { return "GameLog"; }
        }

        static GameLogger()
        {
            ErrorLoggerCounter++;
        }

        public GameLogger(Config config)
        {
            if (!Directory.Exists("Logs"))
                Directory.CreateDirectory("Logs");

            _logFileWriter = new StreamWriter(string.Format("{0}\\Logs\\{1}_{2}.log", config.GameScriptConfig.EnginePath, LoggerName, _loggerNumber));
            _loggerNumber++;
        }


        public void LogInfo(string message, params object[] @params)
        {
            _logFileWriter.WriteLine("[" + ErrorLoggerCounter + "] Info: " + message, @params);
            _logFileWriter.Flush();
        }

        public void LogWarning(string message, params object[] @params)
        {
            _logFileWriter.WriteLine("[" + ErrorLoggerCounter + "] Warning: " + message, @params);
            _logFileWriter.Flush();
        }

        public void LogDebug(string message, params object[] @params)
        {
            _logFileWriter.WriteLine("[" + ErrorLoggerCounter + "] Debug: " + message, @params);
            _logFileWriter.Flush();
        }

        public void LogError(string message, params object[] @params)
        {
            _logFileWriter.WriteLine("[" + ErrorLoggerCounter + "] Error: " + message, @params);
            _logFileWriter.Flush();
        }

        public void LogType(Type scriptType, string message)
        {
            throw new NotImplementedException();
        }
}
now this compile just fine but the following code will not compile.
 public struct GameScriptEngineLogger : ILogger
    {
        private readonly StreamWriter _logFileWriter;

        private static readonly int ErrorLoggerCounter = 0;
        private static int _loggerNumber = 0;

        static GameScriptEngineLogger()
        {
            ErrorLoggerCounter++;
        }

        public string LoggerName
        {
            get { return "ScriptEngineLogger"; }
        }

        public GameScriptEngineLogger(IScriptEngine engine)
        {
            if (!Directory.Exists("Logs"))
                Directory.CreateDirectory("Logs");

            _logFileWriter = new StreamWriter(string.Format("{0}\\Logs\\{1}_{2}.log", engine.Config.GameScriptConfig.EnginePath, LoggerName, _loggerNumber));
            _loggerNumber++;
        }


        public void LogInfo(string message, params object[] @params)
        {
            _logFileWriter.WriteLine("[" + ErrorLoggerCounter + "] Info: " + message, @params);
            _logFileWriter.Flush();
        }

        public void LogWarning(string message, params object[] @params)
        {
            _logFileWriter.WriteLine("[" + ErrorLoggerCounter + "] Warning: " + message, @params);
            _logFileWriter.Flush();
        }

        public void LogDebug(string message, params object[] @params)
        {
            _logFileWriter.WriteLine("[" + ErrorLoggerCounter + "] Debug: " + message, @params);
            _logFileWriter.Flush();
        }

        public void LogError(string message, params object[] @params)
        {
            _logFileWriter.WriteLine("[" + ErrorLoggerCounter + "] Error: " + message, @params);
            _logFileWriter.Flush();
        }

        public void LogType(Type scriptType, string message)
        {
            throw new NotImplementedException();
        }
}
so the second code not compile and throw the error: The this object cannot be use before all of its fields are assigned to. But I don't get why. If before the _logWriter = new ... I write _logWriter = null it compile. What is going on?

comments

albus95 wrote Dec 16, 2014 at 12:31 AM

I solved just a type I should have class not struct....

pgavlin wrote Jan 14, 2015 at 8:18 PM

As you've noticed, this is by design: "_logFileWriter = new StreamWriter(string.Format("{0}\Logs\{1}_{2}.log", engine.Config.GameScriptConfig.EnginePath, LoggerName, _loggerNumber));" uses the "this" parameter of the struct constructor (which is implicit in the call to LoggerName) before all of the struct's fields have been definitely assigned, which is illegal (and generates the error).