Strange C# Compiler Error

Topics: C# Language Design
Dec 15, 2014 at 11:41 PM
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 0 null it compile. What is going on?
Dec 16, 2014 at 12:23 AM
Just guessing but in the ctor of GameScriptEngineLogger you're accessing(this.)LoggerName before the last member in order of assignment (_logFileWriter) is assigned.
The former code snippet works fine because a class has not the same requirements as an struct.
Are you sure you want an struct here?

Side Note:
static GameScriptEngineLogger()
{
    ErrorLoggerCounter++;
}
A static constructor is called only once, therefore ErrorLoggerCounter will always be 1
Dec 16, 2014 at 12:28 AM
I'm stupid I don't know why I write struct here. Thanks.
Also thanks for the ctor think it make no sense increment the count here.
Probably I was using the code snip of reshrper and press struct instead of a class.
Really Stupi error on my side.