【问题标题】:Return false if type properties equals null or 0如果类型属性等于 null 或 0,则返回 false
【发布时间】:2020-01-05 23:04:15
【问题描述】:

我在这里尝试了以下方法:Checking if Object has null in every property。但是,在实例化 Order newOrder = new Order(); 时。我不能简单地实现bool props = newOrder.ArePropertiesNotNull()。我应该在我的 Order 类中添加什么?我在哪里实现ArePropertiesNotNull<T>(this T obj) 的功能?我想知道如果返回的值等于 0 或 null,是否有办法返回 false?

这是我的代码:

OrderProdRepository.cs

...
public bool ReadFromFile(string _date)
        {
            taxesFile.ReadFile();
            productsFile.ReadFile();

            string orderFileName = $"C:\\tempfolder\\Orders_{_date}.txt";

            List<string> lines = File.ReadAllLines(orderFileName).ToList();

            foreach (var line in lines.Skip(1)) //?? new List<string>(0)
            {
                List<string> entry = line.Split(',').ToList();

                Order newOrder = new Order();               
                int.TryParse(entry[0], out int orderNumber);
                newOrder.OrderNumber = orderNumber;
                newOrder.Date = _date;
                newOrder.CustomerName = entry[1];
                newOrder.State = taxesFile.StateAbbreviation(entry[2]);
                newOrder.StateName = taxesFile.StateName(newOrder.State);
                decimal.TryParse(entry[3], out decimal taxRate);
                newOrder.TaxRate = taxesFile.TaxRate(taxRate);
                newOrder.ProductType = productsFile.ProductType(entry[4]);
                decimal.TryParse(entry[5], out decimal area);
                newOrder.Area = area;
                decimal.TryParse(entry[6], out decimal costPerSquareFoot);
                newOrder.CostPerSquareFoot = productsFile.CostPerSquareFoot(costPerSquareFoot);
                decimal.TryParse(entry[7], out decimal laborCostPerSquareFoot);
                newOrder.LaborCostPerSquareFoot = productsFile.LaborCostPerSquareFoot(laborCostPerSquareFoot);
                decimal.TryParse(entry[8], out decimal materialCost);
                newOrder.MaterialCost = materialCost;
                decimal.TryParse(entry[9], out decimal laborCost);
                newOrder.LaborCost = laborCost;
                decimal.TryParse(entry[10], out decimal tax);
                newOrder.Tax = tax;
                decimal.TryParse(entry[11], out decimal total);
                newOrder.Total = total;


                orderList.Add(newOrder);
            }
            return true;
        }
...

【问题讨论】:

  • 为什么你倾向于有一个通用的解决方案而不是实现验证订单是否正确填写的方法?我看到你有值类型属性(十进制、日期时间、整数),你不能只将它们与 null 进行比较。与使用验证方法的方法调用相比,反射非常慢。
  • 如果文件中没有行,您是否尝试返回 false?抱歉,我并不完全清楚您想要的行为是什么。
  • value 来自用户并检查列表中的值,例如 taxesFile.TaxRate(taxRate); 将在列表中未找到时返回 null 或在列表中返回值。如果在任何属性中返回 null,我想返回 false。
  • 最好序列化你的对象。然后你只需要加载/保存你的可序列化对象列表。
  • 我希望我能理解序列化对象的意思,“将对象转换为字节”?这只是 read 方法,还有其他函数可以创建、更新和删除。非常复杂的分配,因为用户只被允许获取列表中可用的内容,所以当它发现一个不在列表中的值时最好立即返回 false 因为太长并且必须等到最后一个值。

标签: c#


【解决方案1】:

我认为您需要一个函数来检查每一行的 null 和/或 0 值:

private bool IsValidLine(string line)
{
    if (line == null)
        return false;

    var arr = line.Split(',');   

    //Uncomment this if splitting the line will always return 11 items array.
    //if (arr.Length < 11)
    //    return false;      

    return arr.Aggregate(0, (n, s) => 
    (decimal.TryParse(s, out decimal d) && d == 0) || 
    string.IsNullOrWhiteSpace(s) ? n + 1 : n) == 0;
}

您可以在代码中使用它,如下所示:

public bool ReadFromFile(string _date)
{
    var orderFileName = $"C:\\tempfolder\\Orders_{_date}.txt";
    var lines = File.ReadAllLines(orderFileName);

    foreach (var line in lines.Skip(1))
    {
        //If parsing any line returns false.
        if (!IsValidLine(line))
            return false;

        //Or if you need to create a list of the valid Order entries.
        if (IsValidLine(line))
        {
            var order = new Order();

            //...

            orderList.Add(newOrder);
        }
    }
    return true;
}

替代方案:

  • Order 类中添加一个静态函数以解析给定的行,如果该行有效,则返回Order 类型的新对象。类似this
  • 如果还不算太晚,请考虑使用本地数据库或序列化。 this 之类的东西,如果你不介意 vb.net 的例子,也许还有 this

【讨论】:

    【解决方案2】:

    您需要将此方法创建为扩展方法。它应该在静态类中定义:

    public static class ObjectExtensions
    {        
        public static bool ArePropertiesNotNull<T>(this T obj)
        {
            return typeof(T).GetProperties().All(propertyInfo => propertyInfo.GetValue(obj) != null);
        }
    }
    

    【讨论】:

    • 我不知道该方法不起作用,除非它是扩展。
    • 我能否使用 ObjectExtensions 方法验证字符串输入?例如newOrder.CustomerName = CharactersValidation(entry[1]); ?
    • @AlejandroH 这个方法应该用来验证对象的属性,它不适用于简单的字符串
    猜你喜欢
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    • 2018-07-30
    • 1970-01-01
    • 1970-01-01
    • 2021-10-03
    • 2015-09-01
    • 1970-01-01
    相关资源
    最近更新 更多