C# 无法序列化Expando对象-Expando对象未实现添加(system.Object)

C# 无法序列化Expando对象-Expando对象未实现添加(system.Object),c#,serialization,expandoobject,C#,Serialization,Expandoobject,您好,我正在创建一个Expando对象列表并将其传递给serialise,我收到了这个错误- 要成为从ienumerable继承的xml可序列化类型,必须具有add的实现,system.dynamic.expando对象不实现add(system.object) 我已经搜索过类似的问题-但我不允许在serialiser上更改任何内容 还有其他方法吗?您可以从DynamicObject派生并实现IXmlSerializable class Program { static void Mai

您好,我正在创建一个Expando对象列表并将其传递给serialise,我收到了这个错误- 要成为从ienumerable继承的xml可序列化类型,必须具有add的实现,system.dynamic.expando对象不实现add(system.object)

我已经搜索过类似的问题-但我不允许在serialiser上更改任何内容


还有其他方法吗?

您可以从
DynamicObject
派生并实现
IXmlSerializable

class Program
{
    static void Main(string[] args) {
        var filePath = @"c:\1.xml";
        dynamic expando = new SerilaizableExpandoObject();
        var serializer = new XmlSerializer(typeof(SerilaizableExpandoObject));

        expando.Name = "Anindya";
        expando.StackOverflowReputation = 100;

        using (var writer = new StreamWriter(filePath)) {
            serializer.Serialize(writer, expando);
        }

        expando = (SerilaizableExpandoObject)serializer.Deserialize(File.OpenRead(filePath));
        Console.WriteLine(expando.Name);
        Console.WriteLine(expando.StackOverflowReputation);
    }
}

public class SerilaizableExpandoObject : DynamicObject, IXmlSerializable, IDictionary<string, object>
{
    private readonly string root = "SerilaizableExpandoObject";
    private readonly IDictionary<string, object> expando = null;

    public SerilaizableExpandoObject() {
        expando = new ExpandoObject();
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result) {
        object value;

        if (expando.TryGetValue(binder.Name, out value)) {
            result = value;
            return true;
        }

        return base.TryGetMember(binder, out result);
    }

    public override bool TrySetMember(SetMemberBinder binder, object value) {
        expando[binder.Name] = value;

        return true;
    }

    public XmlSchema GetSchema() {
        throw new NotImplementedException();
    }

    public void ReadXml(XmlReader reader) {
        reader.ReadStartElement(root);

        while (!reader.Name.Equals(root)) {
            object value;
            string typeContent;
            Type underlyingType;
            var name = reader.Name;

            reader.MoveToAttribute("type");
            typeContent = reader.ReadContentAsString();
            underlyingType = Type.GetType(typeContent);
            reader.MoveToContent();
            expando[name] = reader.ReadElementContentAs(underlyingType, null);
        }
    }

    public void WriteXml(XmlWriter writer) {
        foreach (var key in expando.Keys) {
            var value = expando[key];

            writer.WriteStartElement(key);
            writer.WriteAttributeString("type", value.GetType().AssemblyQualifiedName);
            writer.WriteString(value.ToString());
            writer.WriteEndElement();
        }
    }

    public void Add(string key, object value) {
        expando.Add(key, value);
    }

    public bool ContainsKey(string key) {
        return expando.ContainsKey(key);
    }

    public ICollection<string> Keys {
        get { return expando.Keys; }
    }

    public bool Remove(string key) {
        return expando.Remove(key);
    }

    public bool TryGetValue(string key, out object value) {
        return expando.TryGetValue(key, out value);
    }

    public ICollection<object> Values {
        get { return expando.Values; }
    }

    public object this[string key] {
        get {
            return expando[key];
        }
        set {
            expando[key] = value;
        }
    }

    public void Add(KeyValuePair<string, object> item) {
        expando.Add(item);
    }

    public void Clear() {
        expando.Clear();
    }

    public bool Contains(KeyValuePair<string, object> item) {
        return expando.Contains(item);
    }

    public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex) {
        expando.CopyTo(array, arrayIndex);
    }

    public int Count {
        get { return expando.Count; }
    }

    public bool IsReadOnly {
        get { return expando.IsReadOnly; }
    }

    public bool Remove(KeyValuePair<string, object> item) {
        return expando.Remove(item);
    }

    public IEnumerator<KeyValuePair<string, object>> GetEnumerator() {
        return expando.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator() {
        return this.GetEnumerator();
    }
}
类程序
{
静态void Main(字符串[]参数){
var filePath=@“c:\1.xml”;
dynamic expando=新的SerializableExpandooObject();
var serializer=新的XmlSerializer(typeof(serializableexpandoobject));
expando.Name=“Anindya”;
expando.StackOverflowReputation=100;
使用(var writer=newstreamwriter(filePath)){
serializer.Serialize(writer,expando);
}
expando=(serializableexpandoobject)序列化程序。反序列化(File.OpenRead(filePath));
Console.WriteLine(expando.Name);
Console.WriteLine(expando.StackOverflowReputation);
}
}
公共类SerializableExpandooObject:DynamicObject、IXmlSerializable、IDictionary
{
私有只读字符串root=“SerializableExpandooObject”;
私有只读IDictionary expando=null;
public serializableexpandooobject(){
expando=新的ExpandoObject();
}
公共重写bool TryGetMember(GetMemberBinder绑定器,输出对象结果){
目标价值;
if(expando.TryGetValue(binder.Name,out值)){
结果=值;
返回true;
}
返回base.TryGetMember(活页夹,输出结果);
}
public override bool TrySetMember(SetMemberBinder绑定器,对象值){
expando[binder.Name]=值;
返回true;
}
公共XmlSchema GetSchema(){
抛出新的NotImplementedException();
}
公共void ReadXml(XmlReader){
reader.ReadStartElement(root);
而(!reader.Name.Equals(root)){
目标价值;
字符串类型内容;
下垫式;
var name=reader.name;
阅读器。移动到属性(“类型”);
typeContent=reader.ReadContentAsString();
underlyngType=Type.GetType(typeContent);
reader.MoveToContent();
expando[name]=reader.ReadElementContentAs(underyingType,null);
}
}
public void WriteXml(XmlWriter){
foreach(expando.Keys中的变量键){
var值=expando[键];
writer.writeStart元素(键);
WriteAttributeString(“type”,value.GetType().AssemblyQualifiedName);
writer.WriteString(value.ToString());
writer.writeedelement();
}
}
公共void添加(字符串键、对象值){
expando.Add(键、值);
}
公共bool ContainsKey(字符串键){
返回expando.ContainsKey(键);
}
公共ICollection密钥{
获取{return expando.Keys;}
}
公共布尔删除(字符串键){
返回expando.Remove(键);
}
公共bool TryGetValue(字符串键,输出对象值){
返回expando.TryGetValue(键,输出值);
}
公共ICollection值{
获取{返回expando.Values;}
}
公共对象此[字符串键]{
得到{
返回expando[键];
}
设置{
expando[键]=值;
}
}
公共作废添加(KeyValuePair项){
expando.添加(项目);
}
公共空间清除(){
expando.Clear();
}
public bool包含(KeyValuePair项){
返回expando.Contains(项目);
}
public void CopyTo(KeyValuePair[]数组,int-arrayIndex){
expando.CopyTo(数组、数组索引);
}
公共整数计数{
获取{return expando.Count;}
}
公共图书馆是只读的{
获取{return expando.IsReadOnly;}
}
公共布尔删除(KeyValuePair项){
返回expando.移除(项目);
}
公共IEnumerator GetEnumerator(){
返回expando.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator(){
返回此.GetEnumerator();
}
}

我试图从Expando对象创建一个子类来添加add方法,但Expando对象无法成为子类我正在将Expando对象强制转换到字典中。。此SerializableExpandoobject无法强制转换到字典中…为什么需要将其强制转换到字典中?因为我正在创建动态属性名称-为强类型对象中的每个属性名称加前缀,所以为什么需要ExpandoObject?使用字典就可以了。我已经改变了我的示例,以支持将强制转换为IDictionary