从对象中删除null属性

时间:2013-08-01 07:09:54

标签: c# object properties

,我有一个类,我现在有三个属性,我想做什么,如果在对象中,如果任何一个null或空,那么我想从下面的对象中删除它是我的代码。

public class TestClass
{
    public string Name { get; set; }
    public int ID { get; set; }
    public DateTime? DateTime { get; set; }
    public string Address { get; set; }
}
       TestClass t=new TestClass();
        t.Address="address";
        t.ID=132;
        t.Name=string.Empty;
        t.DateTime=null;

现在我想要TestClass的对象,但是Name和DateTime属性不应该是对象中的对象, 可能吗? 请帮帮我

5 个答案:

答案 0 :(得分:5)

没有从单个对象中删除属性的概念。 类型决定了哪些属性存在 - 而不是单个对象。

特别是,总是有效的方法是这样的:

public void ShowDateTime(TestClass t)
{
    Console.WriteLine(t.DateTme);
}

该代码无法知道您是否想要从DateTime引用的对象中“删除”t属性。如果值为null,它将获得该值 - 这很好。但你不能删除属性本身。

如果您列出某个对象的属性,则应该在那里进行过滤。

编辑:好的,不,你给了我们一些背景信息:

  

确定我使用的是Schemaless数据库,因此null和空值也会在数据库中存储空间,这是原因

因此,在您正在使用的代码中填充该数据库,只是不要设置任何与空值对应的属性字段。这纯粹是数据库群体关注的问题 - 不是对象本身的问题。

(我也认为你应该考虑通过这样做可以节省多少空间。你真的非常关心吗?)

答案 1 :(得分:4)

我很无聊并且在LINQPad中得到了这个

void Main()
{
    TestClass t=new TestClass();
    t.Address="address";
    t.ID=132;
    t.Name=string.Empty;
    t.DateTime=null;

    t.Dump();
    var ret = t.FixMeUp();
    ((object)ret).Dump();
}

public static class ReClasser
{
    public static dynamic FixMeUp<T>(this T fixMe)
    {
        var t = fixMe.GetType();
        var returnClass = new ExpandoObject() as IDictionary<string, object>;
        foreach(var pr in t.GetProperties())
        {
            var val = pr.GetValue(fixMe);
            if(val is string && string.IsNullOrWhiteSpace(val.ToString()))
            {
            }
            else if(val == null)
            {
            }
            else
            {
                returnClass.Add(pr.Name, val);
            }
        }
        return returnClass;
    }
}

public class TestClass
{
    public string Name { get; set; }
    public int ID { get; set; }
    public DateTime? DateTime { get; set; }
    public string Address { get; set; }
}

答案 2 :(得分:1)

可能是接口会很方便:

public interface IAdressAndId
    {
        int ID { get; set; }
        string Address { get; set; }
    }
    public interface INameAndDate
    {
        string Name { get; set; }
        DateTime? DateTime { get; set; }
    }
    public class TestClass : IAdressAndId, INameAndDate
{
    public string Name { get; set; }
    public int ID { get; set; }
    public DateTime? DateTime { get; set; }
    public string Address { get; set; }
}

创建对象:

IAdressAndId t = new TestClass()
            {
                Address = "address",
                ID = 132,
                Name = string.Empty,
                DateTime = null
            };

此外,您可以将您的接口放在单独的命名空间中,并将您的类声明作为内部声明。之后创建一些公共工厂,它们将创建您的类的实例。

答案 3 :(得分:1)

您可以利用dynamic类型:

class Program
{
    static void Main(string[] args)
    {
        List<dynamic> list = new List<dynamic>();
        dynamic
            t1 = new ExpandoObject(),
            t2 = new ExpandoObject();

        t1.Address = "address1";
        t1.ID = 132;

        t2.Address = "address2";
        t2.ID = 133;
        t2.Name = "someName";
        t2.DateTime = DateTime.Now;

        list.AddRange(new[] { t1, t2 });

        // later in your code
        list.Select((obj, index) =>
            new { index, obj }).ToList().ForEach(item =>
        {
            Console.WriteLine("Object #{0}", item.index);
            ((IDictionary<string, object>)item.obj).ToList()
                .ForEach(i =>
                {
                    Console.WriteLine("Property: {0} Value: {1}",
                        i.Key, i.Value);
                });
            Console.WriteLine();
        });

        // or maybe generate JSON
        var s = JsonSerializer.Create();
        var sb=new StringBuilder();
        var w=new StringWriter(sb);
        var items = list.Select(item =>
        {
            sb.Clear();
            s.Serialize(w, item);
            return sb.ToString();
        });

        items.ToList().ForEach(json =>
        {
            Console.WriteLine(json);
        });
    }
}

答案 4 :(得分:0)

这里是已接受答案的“稍微”清晰明了的版本。

        /// <returns>A dynamic object with only the filled properties of an object</returns>
        public static object ConvertToObjectWithoutPropertiesWithNullValues<T>(this T objectToTransform)
        {
            var type = objectToTransform.GetType();
            var returnClass = new ExpandoObject() as IDictionary<string, object>;
            foreach (var propertyInfo in type.GetProperties())
            {
                var value = propertyInfo.GetValue(objectToTransform);
                var valueIsNotAString = !(value is string && !string.IsNullOrWhiteSpace(value.ToString()));
                if (valueIsNotAString && value != null)
                {
                    returnClass.Add(propertyInfo.Name, value);
                }
            }
            return returnClass;
        }