如何解决删除C#
我正在将对象序列化为XML,该XML在某些属性上具有DefaultValue
属性。在某些情况下,我想在序列化期间禁用所有这些默认值。是否可以在运行时删除属性?
[Serializable]
[XmlType(TypeName = "MyType")]
public class MyType
{
public MyType()
{
MyValue = false;
}
[XmlElement(ElementName = "myValue",Form = XmlSchemaForm.Unqualified)]
[DefaultValue(false)]
public bool MyValue { get; set; }
}
public class TestSerializer
{
public void Serialize()
{
XmlSerializer serializer = new XmlSerializer(typeof(MyType));
using (TextWriter writer = new StreamWriter(stream,Encoding.UTF8,1024,true))
{
serializer.Serialize(writer,new MyType());
}
}
}
我已经开始考虑使用反射来完成此操作,但是无法使其正常工作。 XmlAttributeOverrides
似乎也无济于事,但也许我只是还没有找到正确的方法。有什么想法吗?
解决方法
XmlSerializerIgnoringDefaultValuesKey.Create
从this answer到 Force XML serialization of XmlDefaultValue values 基本上可以满足您的需求,但是您通过应用{覆盖了MyValue
的XML元素名称{1}},据说在该答案中未实现:
使用此XmlAttributes对象覆盖时,需要保留的所有属性都需要转移到该新对象中。
以下增强版本支持传输[XmlElement]
,[XmlArray]
和[XmlArrayItem]
覆盖属性:
[XmlElement(ElementName = "myValue",Form = XmlSchemaForm.Unqualified)]
并像这样使用它:
public abstract class XmlSerializerKey
{
static class XmlSerializerHashTable
{
static Dictionary<object,XmlSerializer> dict;
static XmlSerializerHashTable()
{
dict = new Dictionary<object,XmlSerializer>();
}
public static XmlSerializer GetSerializer(XmlSerializerKey key)
{
lock (dict)
{
XmlSerializer value;
if (!dict.TryGetValue(key,out value))
dict[key] = value = key.CreateSerializer();
return value;
}
}
}
readonly Type serializedType;
protected XmlSerializerKey(Type serializedType)
{
this.serializedType = serializedType;
}
public Type SerializedType { get { return serializedType; } }
public override bool Equals(object obj)
{
if (ReferenceEquals(this,obj))
return true;
else if (ReferenceEquals(null,obj))
return false;
if (GetType() != obj.GetType())
return false;
XmlSerializerKey other = (XmlSerializerKey)obj;
if (other.serializedType != serializedType)
return false;
return true;
}
public override int GetHashCode()
{
int code = 0;
if (serializedType != null)
code ^= serializedType.GetHashCode();
return code;
}
public override string ToString()
{
return string.Format(base.ToString() + ": for type: " + serializedType.ToString());
}
public XmlSerializer GetSerializer()
{
return XmlSerializerHashTable.GetSerializer(this);
}
protected abstract XmlSerializer CreateSerializer();
}
public abstract class XmlSerializerWithExtraTypesKey : XmlSerializerKey
{
static IEqualityComparer<HashSet<Type>> comparer;
readonly HashSet<Type> extraTypes = new HashSet<Type>();
static XmlSerializerWithExtraTypesKey()
{
comparer = HashSet<Type>.CreateSetComparer();
}
protected XmlSerializerWithExtraTypesKey(Type serializedType,IEnumerable<Type> extraTypes)
: base(serializedType)
{
if (extraTypes != null)
foreach (var type in extraTypes)
this.extraTypes.Add(type);
}
public Type[] ExtraTypes { get { return extraTypes.ToArray(); } }
public override bool Equals(object obj)
{
if (!base.Equals(obj))
return false;
XmlSerializerWithExtraTypesKey other = (XmlSerializerWithExtraTypesKey)obj;
return comparer.Equals(this.extraTypes,other.extraTypes);
}
public override int GetHashCode()
{
int code = base.GetHashCode();
if (extraTypes != null)
code ^= comparer.GetHashCode(extraTypes);
return code;
}
}
public sealed class XmlSerializerIgnoringDefaultValuesKey : XmlSerializerWithExtraTypesKey
{
readonly XmlAttributeOverrides overrides;
private XmlSerializerIgnoringDefaultValuesKey(Type serializerType,IEnumerable<Type> ignoreDefaultTypes,XmlAttributeOverrides overrides)
: base(serializerType,ignoreDefaultTypes)
{
this.overrides = overrides;
}
public static XmlSerializerIgnoringDefaultValuesKey Create(Type serializerType,bool recurse)
{
XmlAttributeOverrides overrides;
Type [] typesWithOverrides;
CreateOverrideAttributes(ignoreDefaultTypes,recurse,out overrides,out typesWithOverrides);
return new XmlSerializerIgnoringDefaultValuesKey(serializerType,typesWithOverrides,overrides);
}
protected override XmlSerializer CreateSerializer()
{
var types = ExtraTypes;
if (types == null || types.Length < 1)
return new XmlSerializer(SerializedType);
return new XmlSerializer(SerializedType,overrides);
}
static void CreateOverrideAttributes(IEnumerable<Type> types,bool recurse,out XmlAttributeOverrides overrides,out Type[] typesWithOverrides)
{
HashSet<Type> visited = new HashSet<Type>();
HashSet<Type> withOverrides = new HashSet<Type>();
overrides = new XmlAttributeOverrides();
foreach (var type in types)
{
CreateOverrideAttributes(type,overrides,visited,withOverrides);
}
typesWithOverrides = withOverrides.ToArray();
}
static void AddOverride(XmlAttributeOverrides overrides,Type type,MemberInfo memberInfo)
{
var xmlElementAttr = memberInfo.GetCustomAttributes<XmlElementAttribute>();
var xmlArrayAttr = memberInfo.GetCustomAttribute<XmlArrayAttribute>();
var xmlArrayItemAttr = memberInfo.GetCustomAttributes<XmlArrayItemAttribute>();
var attrs = new XmlAttributes
{
XmlDefaultValue = null,XmlArray = xmlArrayAttr,};
foreach (var a in xmlElementAttr)
attrs.XmlElements.Add(a);
foreach (var a in xmlArrayItemAttr)
attrs.XmlArrayItems.Add(a);
overrides.Add(type,memberInfo.Name,attrs);
}
static void CreateOverrideAttributes(Type type,XmlAttributeOverrides overrides,HashSet<Type> visited,HashSet<Type> withOverrides)
{
if (type == null || type == typeof(object) || type.IsPrimitive || type == typeof(string) || visited.Contains(type))
return;
foreach (var property in type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public))
if (overrides[type,property.Name] == null) // Check to see if overrides for this base type were already set.
if (Attribute.IsDefined(property,typeof(DefaultValueAttribute),true))
{
withOverrides.Add(type);
AddOverride(overrides,type,property);
}
foreach (var field in type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public))
if (overrides[type,field.Name] == null) // Check to see if overrides for this base type were already set.
if (Attribute.IsDefined(field,field);
}
visited.Add(type);
if (recurse)
{
var baseType = type.BaseType;
if (baseType != type)
CreateOverrideAttributes(baseType,withOverrides);
}
}
}
演示小提琴here。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。