从对象中删除null属性

,我有一个类,其中我现在有三个属性我想做什么,如果在对象中,如果任何一个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属性不应该是它们在对象中,是否可能? 请帮我

我很无聊,在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(this T fixMe) { var t = fixMe.GetType(); var returnClass = new ExpandoObject() as IDictionary; 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; } } 

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

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

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

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

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

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

好吧我正在使用Schemaless数据库,所以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 }; 

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

您可以利用动态类型:

 class Program { static void Main(string[] args) { List list = new List(); 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)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); }); } } 

因此,接受答案的“略微”更清晰和更短的版本。

  /// A dynamic object with only the filled properties of an object public static object ConvertToObjectWithoutPropertiesWithNullValues(this T objectToTransform) { var type = objectToTransform.GetType(); var returnClass = new ExpandoObject() as IDictionary; 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; }