代码之家  ›  专栏  ›  技术社区  ›  aleemb

C:如何使用反射从泛型对象中移除所有空属性?

  •  2
  • aleemb  · 技术社区  · 15 年前

    我要删除泛型对象中的所有空属性。它不必递归,一级深也可以。

    我需要的原因是json序列化的自定义javascriptconvertor实现,它给了我:{“name”:“aleem”,“age”:null,“type”:“employee”}

    我想跳过空对象。

    此任务的函数接受objct并返回字典:

    IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    

    所以我想从obj中删除所有空属性。所有属性都有getter,但如果未设置该属性,getter将返回 null .

    4 回复  |  直到 15 年前
        1
  •  4
  •   Peter Lillevold Rene    15 年前

    你可以实现你自己的 JavaScriptConverter 以处理类型的序列化。然后可以完全控制属性的序列化方式。

    @Richards Answer提供了序列化方法的一个很好的实现。

    反序列化方法非常类似,但我将把实现留给您。现在javascriptconverter的唯一缺点是它必须从某个地方获得支持的类型。或者像这样硬编码:

    public override IEnumerable<Type> SupportedTypes
    { 
        get
        {
            var list = new List<Type>{ typeof(Foo), typeof(Bar)...};
            return list.AsReadOnly();
        }
    }
    

    …或使其可配置,例如通过类构造函数。

        2
  •  4
  •   Richard    15 年前

    以下几点可能会起到作用:

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

    注意:此方法不处理索引属性。

        3
  •  1
  •   Chad Grant    15 年前
     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);
                    }
                }
            }
        }
    
        4
  •  0
  •   Klathzazt    15 年前

    您可能希望创建某种包装对象,该对象仅在成员不为空时公开其包装的内容。

    您可能还想查看C的版本4。从 the wikipedia entry for duck typing :

    第4版C有额外的 键入指示 安排类型检查的编译器 在运行时发生的类 而不是编译时,包括 中的运行时类型检查代码 编译输出。这样的增加允许 最喜欢的语言 鸭子打字的好处 缺点是需要识别 并在 编译时。