Сериализация состояния объекта в const C # class - PullRequest
0 голосов
/ 08 февраля 2012

Пару раз я обнаруживал, что хочу взять состояние объекта и сделать его постоянным. Например. Я проектирую пользовательский интерфейс, который отображает информацию, скажем, из вызова базы данных. и я просто хочу получить образец данных, чтобы поиграть, чтобы я мог видеть, как все будет выглядеть.

Допустим, у меня есть:

public interface IPerson
{
   string Name{get;}
   string Age {get;}
   ...
}

public class Person
{
   string Name{get; set}
   string Age {get; set}
   ...

}

и некоторый метод, который говорит вызов базы данных или что-либо еще, чтобы загрузить его. В этом примере для простоты скажем, что он загружает его из файла CSV: для этого примера файл содержит: «Mrs McKenzy, 56, ..»

IPerson Load(string fileName)
{
    var text = File.ReadAllText(filename);
    var parts = text.Split(",");
    return new Person()
    {
        Name = parts[0],
        Age = Int32.Parse(parts[1]),
        ...
    }
}

из этого я хочу сгенерировать пример моего класса: (как файл .cs)

public class SamplePerson : IPerson
{
    string Name{get {return "Mrs McKenzy"}}
    string Age {get {return 56}}
    ...  
}

Единственный способ убедиться в этом - это сериализовать объект (например, в XML, чтобы я мог видеть, что в нем), и затем мой SamplePerson десериализует объект в его конструкторе, чтобы инициализировать себя. Теперь это не плохое решение. Но я полагаю, что было бы лучше, если бы я мог просто "Serialise to C #". Кажется, что-то, что можно собрать без слишком особых проблем с отражением, поэтому мне интересно, есть ли какая-то существующая библиотека для этого. (Если нет, я думаю, это может быть интересный проект, если я когда-нибудь получу скуку)

Ответы [ 3 ]

0 голосов
/ 08 февраля 2012

Как я понимаю, вы хотите сохранить свойства объекта как жестко закодированное значение.Зачем это делать?

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

// make a public interface
public interface IPerson {
    String Name { get; }
    String Age { get; }
}

public class Manager {
    public IEnumerable<IPerson> GetPeople() {
        var retVal = new List<Person>();
        // Do your retrieval. Here you can access
        // the setters of your class. 
        return retVal;
    }
    // make a private implementation
    private class Person : IPerson {
        public String Name { get; set; }
        public String Age { get; set; }

        // explicit interface implementation
        String IPerson.Name {
            get { return Name; }
        }

        String IPerson.Age {
            get { return Age; }
        }
    }
}

Этот подход позволяет скрыть фактическую реализацию и ограничить доступ к свойствам, делая их доступными только для чтения.

0 голосов
/ 08 февраля 2012

Как насчет этого, используя CSharpCodeProvider, скомпилируйте свой класс, затем создайте его экземпляр и используйте динамику .....

void Main()
{
    dynamic instanceOfMyType;

    using (CSharpCodeProvider csharpCodeProvider = new CSharpCodeProvider())
    {

        var outPutFile = Path.ChangeExtension(Path.GetTempFileName(), ".dll");
        CompilerParameters parameters = new CompilerParameters()
        {
            //For creating DLLs it should be false
            GenerateExecutable = false,
            OutputAssembly = outPutFile,
            //For displaying warnings in the compilerResults
            WarningLevel = 4,

        };
        //I am reading the text from a WPF RichTextbox
        var text = File.ReadAllText(@"c:\temp\SampleFoo.cs");
        CompilerResults compilerResults = csharpCodeProvider.CompileAssemblyFromSource(parameters, text);

        var type = compilerResults.CompiledAssembly.GetType("SampleFoo");
        instanceOfMyType = Activator.CreateInstance(type);
    }
    Console.WriteLine (instanceOfMyType.Bar);
}

* Как скомпилировать фрагмент кода C # во время выполнения


или вы можете поделиться IPerson как dll в классе SamplePerson .....

........

0 голосов
/ 08 февраля 2012

Возможно, вы можете абстрагировать механизм от интерфейса, что-то вроде:

public interface IPersonRepository
{
  IPerson GetPerson(int id);
}

И обеспечить реализацию во время разработки.

public class DesignTimePersonRepository : IPersonRepository
{
  public IPerson GetPerson(int id)
  {
    return new DesignTimePerson { Name = "Joe Bloggs", Age = 56 };
  }
}

Теперь, при условии, что вы можете определить, можете ли выВы находитесь в режиме разработки или нет, вы могли бы сделать что-то вроде:

public IPersonRepository GetPersonRepository()
{
  return DesignMode
    ? new DesignTimePersonRepository()
    : _container.Resolve<IPersonRepository>();
}
...