,我有一个类,我现在有三个属性,我想做什么,如果在对象中,如果任何一个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属性不应该是对象中的对象, 可能吗? 请帮帮我
答案 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;
}