Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Глюк с с сериализацией.


Автор: Хоббит 20.2.2008, 21:04
Словил интересный глюк.

Приложение представляет собой комплекс логических игр. Каждая игры подключается в виде отдельной сборки. В каждой игре есть опции (класс опций). Опции сохраняются в файл и загружаются с помощью сериализации. То есть.

Есть базовый Game, GameOptions и конкретные реализации

Код

class Game
{
  public GameOptions {get; set;}
}

class GameOptions
{
  public Color Prop1 {get; set}
  ...
}


В сборке для игры.
Код

class ListWordGame : Game
{
  public ListWordGameOptions {get {return base.Options;} set {base.Options = value;}
...
}

class ListWordGameOptios : GameOptions
{
   ...
}


При создание обьекта WordGame в конструкторе Game вызывается метод Read для загрузки опций
Код

FileStream fileStream = null;
            try
            {
// Пробуем загрузить
                fileStream = new FileStream(this.path, FileMode.Open);
                BinaryFormatter binaryFormatter = new BinaryFormatter();
// Тут вылетает эксцептион
                this.Options = (ListWordGameOptions)binaryFormatter.Deserialize(fileStream);
                fileStream.Close();
                
            }
            catch (Exception e)
            {
                try
                {
// Не получилось пробуем закрыть поток
                    fileStream.Close();
                }
                catch
                {
                }
// Удаляем файл, так как он наверно сбойный
                if (File.Exists(this.path))
                {
                    File.Delete(this.path);
                }
// Задаем значение по умолчанию
                this.Options = new ListWordGameOptions();
            }            


Так вот, если создать обычную формочку. Указать ссылку на сборку в Reflections. Создать клас игры и запустить, то все работает. Опции загружаются и сохраняются.

Но в рабочем приложении все происходит следующим образом.
Сборка подгружается через Assembly.LoadFile
В ней ищутся классы наследованые от Game и создаётся объект класса по средством Activator.CreateInstance
Так вот в том случае в указанном в коде месте возникает исключение с следющим сообщением
Unable cast object of type 'ListWordGameOptios' to type 'ListWordGameOptions'.

Не пойму в чем дело.

Автор: QryStaL 20.2.2008, 21:16
'ListWordGameOptios' to type
'ListWordGameOptions'

Похоже на опечатку

Автор: Хоббит 21.2.2008, 11:00
это я в ручную печатал. В ошибке то все верно написано. В общем он говорит, что не может переделать этот тип в этот же тип.

Автор: Хоббит 23.2.2008, 12:21
Вот простой пример.

Код

namespace SerializedTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly serializerAssembly = Assembly.LoadFile(Path.GetFullPath("SerializerAssembly.dll"));            
            Type serializerDirectorType = serializerAssembly.GetType("SerializerAssembly.SerializerDirector");
            try
            {
                Activator.CreateInstance(serializerDirectorType);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            Console.ReadLine();
        }        
    }
}

namespace SerializerAssembly
{    
    public class SerializerDirector
    {
        #region Constructors
        public SerializerDirector()
        {
            this.Load();
        }
        #endregion

        #region Methods
        public void Load()
        {            
            try
            {
                string path = "file.txt";
                TestClass testClass;
                Serializer serializer = new Serializer();

                if (File.Exists(path) == false)
                {
                    testClass = new TestClass();
                    testClass.IntField = 10;
                    testClass.ColorField = Color.Beige;
                    serializer.Serialize(path, testClass);
                }
                else
                {
                    testClass = (TestClass)serializer.Deserialize(path);
                }

                Console.WriteLine(testClass.IntField.ToString());
                Console.WriteLine(testClass.ColorField.ToString());
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            
            Console.ReadLine();
        }
        #endregion
    } 
}

namespace SerializerAssembly
{
    public class Serializer
    {
        #region Constructors
        public Serializer()
        {
        }
        #endregion

        #region Methods
        public void Serialize(string path, object item)
        {
            FileStream fileStream = new FileStream(path, FileMode.Create);
            BinaryFormatter binaryFormatter = new BinaryFormatter();
            binaryFormatter.Serialize(fileStream, item);
            fileStream.Close();
        }

        public object Deserialize(string path)
        {
            FileStream fileStream = new FileStream(path, FileMode.Open);
            BinaryFormatter binaryFormatter = new BinaryFormatter();
            object item = binaryFormatter.Deserialize(fileStream);
            fileStream.Close();
            return item;
        }
        #endregion
    }
}

namespace SerializerAssembly
{
    [Serializable]    
    public class TestClass
    {
        #region Fields
        private int intField;
        private Color colorField;
        #endregion

        #region Constructors
        public TestClass()
        {
            this.intField = 1;
            this.colorField = Color.Aqua;
        }
        #endregion

        #region Properties
        public int IntField
        {
            get
            {
                return this.intField;
            }
            set
            {
                this.intField = value;
            }
        }

        public Color ColorField
        {
            get
            {
                return this.colorField;
            }
            set
            {
                this.colorField = value;
            }
        }
        #endregion
    }
}


Вот что выдает теперь.
Unable to find assembly 'SerialiserAssembly, Version=1.0.0.0, Culture=neutral, P
ublicKeyToken=null'.

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

Добавлено через 2 минуты и 44 секунды
Вот простой пример.

[code=csharp]
namespace SerializedTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly serializerAssembly = Assembly.LoadFile(Path.GetFullPath("SerializerAssembly.dll"));            
            Type serializerDirectorType = serializerAssembly.GetType("SerializerAssembly.SerializerDirector");
            try
            {
                Activator.CreateInstance(serializerDirectorType);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            Console.ReadLine();
        }        
    }
}

namespace SerializerAssembly
{    
    public class SerializerDirector
    {
        #region Constructors
        public SerializerDirector()
        {
            this.Load();
        }
        #endregion

        #region Methods
        public void Load()
        {            
            try
            {
                string path = "file.txt";
                TestClass testClass;
                Serializer serializer = new Serializer();

                if (File.Exists(path) == false)
                {
                    testClass = new TestClass();
                    testClass.IntField = 10;
                    testClass.ColorField = Color.Beige;
                    serializer.Serialize(path, testClass);
                }
                else
                {
                    testClass = (TestClass)serializer.Deserialize(path);

Добавлено через 2 минуты и 55 секунд
Вот простой пример.

[code=csharp]
namespace SerializedTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly serializerAssembly = Assembly.LoadFile(Path.GetFullPath("SerializerAssembly.dll"));            
            Type serializerDirectorType = serializerAssembly.GetType("SerializerAssembly.SerializerDirector");
            try
            {
                Activator.CreateInstance(serializerDirectorType);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            Console.ReadLine();
        }        
    }
}

namespace SerializerAssembly
{    
    public class SerializerDirector
    {
        #region Constructors
        public SerializerDirector()
        {
            this.Load();
        }
        #endregion

        #region Methods
        public void Load()
        {            
            try
            {
                string path = "file.txt";
                TestClass testClass;
                Serializer serializer = new Serializer();

                if (File.Exists(path) == false)
                {
                    testClass = new TestClass();
                    testClass.IntField = 10;
                    testClass.ColorField = Color.Beige;
                    serializer.Serialize(path, testClass);
                }
                else
                {
                    testClass = (TestClass)serializer.Deserialize(path);

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)