C# 从对象中删除null属性

C# 从对象中删除null属性,c#,object,properties,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; } }

,我有一个类,其中我有三个属性,现在我想做的是,如果在对象中,如果任何一个为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的对象,但在该名称和DateTime属性中,它们不应该在对象中, 可能吗?
请帮助我

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

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

public void ShowDateTime(TestClass t)
{
    Console.WriteLine(t.DateTme);
}
该代码无法知道是否要从
t
引用的对象中“删除”DateTime属性。如果该值为null,它将只获取该值-这很好。但是你不能移除属性本身

如果你在某处列出一个对象的属性,你应该在那里进行过滤

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


好的,我使用的是无模式数据库,所以null和空值也会在数据库中存储空间,这就是原因

因此,在填充该数据库的代码中,不要设置与属性对应的任何字段。这纯粹是一个数据库填充问题,而不是对象本身的问题


(我也认为,你应该考虑这样做会节省多少空间。你真的很在乎吗?)

界面可能很方便:

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

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

您可以利用以下类型:

类程序
{
静态void Main(字符串[]参数)
{
列表=新列表();
动态
t1=新的ExpandoObject(),
t2=新的ExpandoObject();
t1.Address=“address1”;
t1.ID=132;
t2.Address=“address2”;
t2.ID=133;
t2.Name=“someName”;
t2.DateTime=DateTime.Now;
AddRange(新[]{t1,t2});
//稍后在代码中
列表。选择((对象,索引)=>
新建{index,obj}).ToList().ForEach(项=>
{
WriteLine(“对象{0}”,item.index);
((IDictionary)item.obj).ToList()
.ForEach(i=>
{
WriteLine(“属性:{0}值:{1}”,
i、 关键,即价值);
});
Console.WriteLine();
});
//或者生成JSON
var s=JsonSerializer.Create();
var sb=新的StringBuilder();
var w=新的StringWriter(sb);
变量项=列表。选择(项=>
{
(某人清楚地);
s、 序列化(w,项);
使某人返回字符串();
});
items.ToList().ForEach(json=>
{
Console.WriteLine(json);
});
}
}

我很无聊,在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; }
}
void Main()
{
TestClass t=新的TestClass();
t、 Address=“Address”;
t、 ID=132;
t、 Name=string.Empty;
t、 DateTime=null;
t、 Dump();
var ret=t.FixMeUp();
((object)ret.Dump();
}
公共静态类重分类器
{
公共静态动态修复(此T修复)
{
var t=fixMe.GetType();
var returnClass=new ExpandoObject()作为IDictionary;
foreach(t.GetProperties()中的var pr)
{
var val=pr.GetValue(fixMe);
if(val为string&&string.IsNullOrWhiteSpace(val.ToString()))
{
}
else if(val==null)
{
}
其他的
{
returnClass.Add(请购单名称,val);
}
}
返回类;
}
}
公共类TestClass
{
公共字符串名称{get;set;}
公共int ID{get;set;}
公共日期时间?日期时间{get;set;}
公共字符串地址{get;set;}
}

特此提供一个“稍微”更清晰、更简短的公认答案版本

        /// <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;
        }
///仅具有对象的填充属性的动态对象
公共静态对象转换为不带Null值的OutProperties的对象(此T对象转换)
{
var type=objectToTransform.GetType();
var returnClass=new ExpandoObject()作为IDictionary;
foreach(type.GetProperties()中的var propertyInfo)
{
var值=propertyInfo.GetValue(objectToTransform);
var valueIsNotAString=!(值为string&!string.IsNullOrWhiteSpace(value.ToString());
if(valueIsNotAString&&value!=null)
{
returnClass.Add(propertyInfo.Name,value);
}
}
返回类;
}

您所说的“删除”是什么意思?我不想在TestClassObject中使用该属性,为什么您需要删除它。在使用不能删除属性的类时,有很多方法不考虑它,除非您永久删除它。但是,您可以在类层次结构中创建多个类,其中一个类有属性,另一个没有。好的,我使用的是无模式数据库,所以null和empty值也会在数据库中存储空间,这就是原因。是的,因为我的数据库中每天插入2,50000条记录,我必须检索该记录并对其执行一些计算,所以我必须处理这个问题。@DhavalPatel:have您实际测量了数据和检索时间方面的差异有多大?我怀疑它是非常小的:在我的数据库中,有一个触发器,当它达到85,00000的限制时,它可以从一个表数据移动到另一个表数据,所以在表中超过30天后,应该有大约60,00,00个数据,我使用的是silverlight应用程序,它需要时间来加载数据
        /// <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;
        }