将对象状态序列化为const C#类

时间:2012-02-08 14:07:07

标签: c# .net serialization reflection code-generation

有几次,我发现自己想要获取一个物体的状态,然后将它变成一个常数。 例如。我正在设计一个UI,它显示数据库调用的信息。 我只想要一个数据样本,所以我可以看到一切都会是什么样的。

我想说:

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在其构造函数中反序列化该对象,以便对其进行初始化。 现在这不是一个糟糕的解决方案。 但我认为如果我能够“串行化到C#”会更好。 似乎可以放在一起而没有太多反射很麻烦的东西, 所以我想知道是否有一些现有的库。 (如果不是,我猜它可能是一个有趣的项目,如果我得到bord)

3 个答案:

答案 0 :(得分:0)

也许您可以将机制抽象为接口,例如:

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

答案 1 :(得分:0)

据我所知,您希望将对象属性保存为硬编码值。 为什么这样做?

根据您的标记我可以猜测您希望能够获得但不设置值。 如果是这种情况,您可以使用以下方法。

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

此方法允许您隐藏实际实现并限制对属性的访问,使其只能读取。

答案 2 :(得分:0)

如何使用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);
}

* How to compile C# code snippet in runtime


或者您可以在SamplePerson类中共享IPerson作为dll .....

........