【问题标题】:Serialise object state to const C# class将对象状态序列化为 const C# 类
【发布时间】:2012-02-29 23:32:57
【问题描述】:

有几次,我发现自己想要获取对象的状态,并将其变为常量。 例如。我正在设计一个 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}}
    ...  
}

我能看到的唯一方法是将对象序列化(prob to XML,所以我可以看到其中的内容),然后让我的 SamplePerson 在其构造函数中反序列化对象,以初始化自身。 现在这不是一个糟糕的解决方案。 但我认为如果我可以“序列化为 C#”会更好。 似乎可以放在一起而没有太多麻烦的反射, 所以我想知道是否有一些现有的图书馆。 (如果没有,我想如果我有兴趣,这可能是一个有趣的项目)

【问题讨论】:

  • 你描述的是代码生成,不是序列化
  • 它被标记为代码生成。在这种情况下,它是一种序列化(至少在我看来)我所做的大多数代码生成都涉及以一种语言生成代码并以另一种语言生成代码——例如领域特定语言的东西。这是关于持久化对象状态的地方

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


【解决方案1】:

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

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

【讨论】:

  • 我已经有了这样的系统。我想摆脱不得不手工输入的工作: new DesignTimePerson { Name = "Joe Bloggs", Age = 56 }; (在我的真实代码中实际上有很多字段(例如,它是一个类似树的结构,但为了示例,我将它大量简化))
【解决方案2】:

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

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

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

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

【讨论】:

  • 不,对不起,我显然没能说清楚。我想获取对象的当前状态。并生成一个 .cs 文件,其中包含另一个类(共享接口),它的所有字段都作为(理想的编译时间)常量。
  • @Oxinabox 那么我只能建议你成为 google 的好朋友,使用 Dynamic, class, .net, reflection, emit 的不同组合,深入研究操作码并制作你自己的类生成器,以满足你的特定需求。祝你好运))
  • 可能是一个有趣的下午。似乎有人已经这样做了。 (我可能会对 codeplex 有所了解)
【解决方案3】:

怎么样,使用 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 共享.....

........

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-09
    • 1970-01-01
    • 2020-07-19
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 2018-05-25
    相关资源
    最近更新 更多