3

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

4

5 回答 5

5

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

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

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

该代码无法知道您是否想从所引用DateTime的对象中“删除”该属性。t如果该值为空,它只会获得该值 - 没关系。但是您不能删除该属性本身。

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

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

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

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

(我还认为您应该考虑这样做会真正节省多少空间。您真的那么在意吗?)

于 2013-08-01T07:12:02.100 回答
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; }
}
于 2013-08-01T07:50:45.637 回答
3

特此“稍微”更清晰和更短的版本接受的答案。

        /// <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;
        }
于 2018-10-25T09:51:40.623 回答
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
            };

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

于 2013-08-01T07:26:13.547 回答
1

您可以利用动态类型:

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);
        });
    }
}
于 2013-08-01T07:26:30.720 回答