简体   繁体   中英

Serialise object state to const C# class

A couple of times, i've found myself wanting to take the state of an object, and make it into a constant. Eg. I'm designing a UI, that displays informatation from say a database call. and I just want a sample of the data to play around with, so i can see what everything would look like.

Let say I have:

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

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

}

and some method that does say the database call, or what ever to load it. For this example lets say for simpicities sake it loads it from a CSV file: for this example the file contains: "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]),
        ...
    }
}

from this I want to generate my sample class: (as a .cs file)

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

The only way I can see of doing this is serialise the object (prob to XML, so i can see what is in it), and then have my SamplePerson deserialise the object in its constructor, to intitialise itself. Now this isn't a bad solution. But I figure it would be nicer if I could just "Serialise to C#". Seems like something that could be put together without too much trouble with reflection, so I'm wondering if there is some existing library for it. (If not I guess it could be a fun project if ever I get bord)

Perhaps you can abstract the mechanism to an interface, something like:

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

And provide a design-time implementation.

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

Now, assuming you can determine whether you're in Design mode, or not, you could do something like:

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

As I understand you want to save the object properties as a hard coded value. Why to do so?

According to your markup I can guess you wish to be able to get but not set the value. If this is a case you might use the following approach.

// 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; }
        }
    }
}

This approach allows you to hide the actual implementation and restrict the access to the properties making them only readable.

How about this, using the CSharpCodeProvider, compile your class, then instance it and use dynamics.....

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);
}

* How to compile C# code snippet in runtime


or you can share the IPerson as a dll en the SamplePerson class.....

........

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM