我尝试编写自己的序列化程序。但是这个序列化程序只序列化属性。如何序列化字段?我所拥有的课程如下所示:
namespace MySerializer
{
class MySerializer
{
private Type targetType;
public MySerializer(Type targetType)
{
this.targetType = targetType;
if (!targetType.IsDefined(typeof(DataContractAttribute), false))
throw new Exception("No soup for you");
}
public void WriteObject(Stream stream, Object graph)
{
IEnumerable<PropertyInfo> serializbleProperties =
targetType.GetProperties().Where(p => p.IsDefined(typeof (DataMemberAttribute), false));
var writer = new StreamWriter(stream);
writer.WriteLine("<" + targetType.Name + ">");
foreach (PropertyInfo propInfo in serializbleProperties)
writer.Write("\t<" + propInfo.Name + ">" + propInfo.GetValue(graph, null) +
"</" + propInfo.Name + ">");
writer.WriteLine("</" + targetType.Name + ">");
writer.Flush();
}
}
}
[DataContract]
class Person
{
[DataMember]
public string _family;
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
[DataMember]
public int Age { get; set; }
}
class Program
{
static void Main(string[] args)
{
Person name = new Person
{
_family = "big",
FirstName = "Vasy",
LastName = "Bobrow",
Age = 20
};
MySerializer serializer = new MySerializer(name.GetType());
MemoryStream someRam = new MemoryStream();
serializer.WriteObject(someRam, name);
someRam.Seek(0, SeekOrigin.Begin);
Console.WriteLine(XElement.Parse(
Encoding.ASCII.GetString(someRam.GetBuffer()).Replace("\0", "")));
}
}
要序列化字段,我可以使用FieldsInfo而不是PropetryInfo,还是有另一种方式?
答案 0 :(得分:3)
这个问题实际上并不是关于序列化,而是关于如何进行反思。如果要返回字段和属性,则需要使用方法GetMembers
并指定要查找属性和字段。
public void WriteObject(Stream stream, Object graph)
{
IEnumerable<MemberInfo> serializbleMembers =
targetType.GetMembers(BindingFlags.GetField | BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic )
.Where(p => p.IsDefined(typeof (DataMemberAttribute), false));
var writer = new StreamWriter(stream);
writer.WriteLine("<" + targetType.Name + ">");
foreach (MemberInfo memberInfo in serializbleMembers)
{
writer.Write("\t<" + memberInfo.Name + ">");
var fieldInfo = memberInfo as FieldInfo;
if(fieldInfo != null)
{
writer.Write(fieldInfo .GetValue(graph, null).ToString());
}
var propInfo= memberInfo as PropertyInfo;
if(propInfo != null)
{
writer.Write(propInfo.GetValue(graph, null).ToString());
}
writer.Write("</" + memberInfo.Name + ">");
}
writer.WriteLine("</" + targetType.Name + ">");
writer.Flush();
}
但是我怀疑你的WriteObject方法非常有用,你和我的WriteObject
方法都依赖于.ToString()
值被覆盖(当你这样做时,你的.ToString()
值隐含">" +
+
.ToString()
[DataContract]
class Example
{
public Example()
{
ExampleArray = new int[] {1, 2};
}
[DataMember]
int[] ExampleArray {get; set;}
}
右侧的任何内容<Example>
<ExampleArray>System.Int32[]</ExampleArray >
</Example>
为您调用了它。例如,您尝试使用类似
.ToString()
你会得到
.GetType().Name
作为输出,因为任何未覆盖{{1}}的类只会覆盖输出{{1}}。