我想删除通用对象中的所有null属性。它不一定是递归的,一层深也没关系。
我需要的原因是JSON序列化的自定义JavascriptConvertor实现,它给了我:{“Name”:“Aleem”,“Age”:null,“Type”:“Employee”}
我想跳过null对象。
此任务的函数接受objct并返回一个Dictionary:
IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
所以我想从obj中删除所有null属性。所有属性都有getter,但如果未设置该属性,则getter返回null
。
答案 0 :(得分:4)
您可以实现自己的JavaScriptConverter来处理类型的序列化。然后,您可以完全控制属性的序列化方式。
@Richards回答提供了一个很好的Serialize方法实现。
反序列化方法非常相似,但我会将实现留给您。现在JavaScriptConverter的唯一缺点是它必须从某个地方获取支持的类型。要么像这样硬编码:
public override IEnumerable<Type> SupportedTypes
{
get
{
var list = new List<Type>{ typeof(Foo), typeof(Bar)...};
return list.AsReadOnly();
}
}
...或使其可配置,例如通过类构造函数。
答案 1 :(得分:4)
以下内容可能会解决问题:
public IDictionary<string, object> GetNonNullProertyValues(object obj)
{
var dictionary = new Dictionary<string, object>();
foreach (var property in obj.GetType().GetProperties())
{
var propertyValue = property.GetValue(obj, null);
if (propertyValue != null)
{
dictionary.Add(property.Name, propertyValue);
}
}
return dictionary;
}
注意:此方法不处理索引属性。
答案 2 :(得分:1)
using System.IO;
using System.Runtime.Serialization.Json;
public static class JsonExtensions
{
public static string ToJson<T>(this T instance)
{
var serializer = new DataContractJsonSerializer(typeof(T));
using (MemoryStream memoryStream = new MemoryStream())
{
serializer.WriteObject(memoryStream, instance);
memoryStream.Flush();
memoryStream.Position = 0;
using (var reader = new StreamReader(memoryStream))
{
return reader.ReadToEnd();
}
}
}
public static T FromJson<T>(this string serialized)
{
var serializer = new DataContractJsonSerializer(typeof(T));
using (MemoryStream memoryStream = new MemoryStream())
{
using (StreamWriter writer = new StreamWriter(memoryStream))
{
writer.Write(serialized);
writer.Flush();
memoryStream.Position = 0;
return (T)serializer.ReadObject(memoryStream);
}
}
}
}
答案 3 :(得分:0)
您可能想要创建某种包装对象,只有在它们不为空时才会公开它所包装的成员。
您可能还想查看C#的第4版。来自the wikipedia entry for duck typing:
C#的第4版发布有额外的 类型注释指示 编译器安排类型检查 在运行时发生的类而不是 比编译时间,包括 运行时类型检查代码 编译输出。这样的添加允许 享受大部分的语言 只有鸭子打字的好处 缺点是需要识别 并指定这样的动态类 编译时间。