繁体   English   中英

检查 class 中的任何属性是否为 null

[英]Check whether any property within class is null

我正在编写一个简单的控制台天气应用程序(OpenWeatherMap),我想验证来自 OWM 的响应是否包含任何 null 属性。 这是我的 class 包含属性:

public class WeatherMain
    {
        public Coord coord { get; set; }
        public List<Weather> weather { get; set; }
        public Main main { get; set; }
        public Wind wind { get; set; }
        public Rain rain { get; set; }
        public Snow snow { get; set; }
        public Clouds clouds { get; set; }
        public Sys sys { get; set; }
        [JsonProperty("base")]
        public string _base { get; set; }
        public int? visibility { get; set; }
        public int? timezone { get; set; }
        public int? id { get; set; }
        public string name { get; set; }
        public int? cod { get; set; }
    }

正如你所看到的,还有一些包含它们自己的属性的类。 我想检查一下,如果这些基本上是 null,那么我可以在控制台中告知缺失值。 现在,我使用 IF 对 WeatherMain 属性进行了一些基本检查:

    public static string PrepareResponse(WeatherMain input)
    {
        string cityName, main, visibility, wind, clouds, rain, snow, coord;

        if (input.name == null)
            cityName = "City name section not found\n";
        else
            cityName = $"\nCity name: {input.name}\n";
        if (input.main == null)
            main = "Main section not found\n";
        else
        {
            main = $"Main parameters:\n\tTemperature: {input.main.temp}C\n\t" +
            $"Temperature max.: {input.main.temp_max}C\n\tTemperature min.: {input.main.temp_min}C" +
            $"\n\tFeels like: {input.main.feels_like}C\n\tPressure: {input.main.pressure}hPA\n\t" +
            $"Humidity: {input.main.humidity}%\n";
        }
        if (input.visibility == null)
            visibility = "Visibility section not found\n";
        else
            visibility = $"Visibility: {input.visibility}m\n";
        if (input.wind == null)
            wind = "Wind section not found\n";
        else
            wind = $"Wind:\n\tSpeed: {input.wind.speed}m/s\n\tDirection: {input.wind.deg}deg\n";
        if (input.clouds == null)
            clouds = "Clouds section not found\n";
        else
            clouds = $"Clouds: {input.clouds.all}%\n";
        if (input.rain == null)
            rain = "Rain section not found\n";
        else
            rain = $"Rain: {input.rain._1h}mm\n";
        if (input.snow == null)
            snow = "Snow section not found\n";
        else
            snow = $"Snow: {input.snow._1h}mm\n";
        if (input.coord == null)
            coord = "Coordinates section not found\n";
        else
            coord = $"Coordinates:\n\tLatitude: {input.coord.lat}\n\tLongitude: {input.coord.lon}\n";

        string outputString = cityName + main + visibility + wind + clouds + rain + snow + coord;

        return outputString;
    }

我正在考虑将这些属性放入一个集合中,并一一检查 null 并可能将值更改为字符串。 我想有更好的方法可以做到这一点。 有任何想法吗?

您可以通过使用反射命名空间来做到这一点:

        var weather = new WeatherMain
        {
            visibility = 2,
            timezone = 5
        };

        Type t = weather.GetType();
        Console.WriteLine("Type is: {0}", t.Name);
        PropertyInfo[] props = t.GetProperties();
        Console.WriteLine("Properties (N = {0}):",
                          props.Length);
        foreach (var prop in props)
            if (prop.GetValue(weather) == null)
            {
                Console.WriteLine("   {0} ({1}) is null", prop.Name,
                                  prop.PropertyType.Name);
            }

这是一个小提琴样本: https://dotnetfiddle.net/MfV7KD

使用描述符 class,您可以将值访问、null 消息和格式化的 output 合并到一个地方,然后循环它们。

首先, Parameter class 将描述每个参数:

public class Parameter {
    public Func<WeatherMain, object> Value;
    public string NullName;
    public Func<WeatherMain, string> FormatSection;
}

然后, static List将描述您要测试的所有参数和 output:

public static List<Parameter> Parameters = new[] {
        new Parameter { Value = w => w.name, NullName = "City name", FormatSection = w => $"City name: {w.name}" },
        new Parameter { Value = w => w.main, NullName = "Main",
                        FormatSection = w => $"Main parameters:\n\tTemperature: {w.main.temp}C\n\t" +
                                             $"Temperature max.: {w.main.temp_max}C\n\tTemperature min.: {w.main.temp_min}C" +
                                             $"\n\tFeels like: {w.main.feels_like}C\n\tPressure: {w.main.pressure}hPA\n\t" +
                                             $"Humidity: {w.main.humidity}%" },

        new Parameter { Value = w => w.visibility, NullName = "Visibility", FormatSection = w => $"Visibility: {w.visibility}" },
        new Parameter { Value = w => w.wind, NullName = "Wind", FormatSection = w => $"Wind:\n\tSpeed: {w.wind.speed}m/s\n\tDirection: {w.wind.deg}deg" },
        new Parameter { Value = w => w.clouds, NullName = "Clouds", FormatSection = w => $"Clouds: {w.clouds.all}%" },
        new Parameter { Value = w => w.rain, NullName = "Rain", FormatSection = w => $"Rain: {w.rain._1h}mm" },
        new Parameter { Value = w => w.snow, NullName = "Snow", FormatSection = w => $"Snow: {w.snow._1h}mm" },
        new Parameter { Value = w => w.coord, NullName = "Coordinates", FormatSection = w => $"Coordinates:\n\tLatitude: {w.coord.lat}\n\tLongitude: {w.coord.lon}" },
    }.ToList();

最后,您可以通过遍历列表来生成格式化的响应:

public static string PrepareResponse(WeatherMain input) {
    var ans = new List<string>();

    foreach (var p in Parameters) {
        if (p.Value(input) == null)
            ans.Add($"{p.NullName} section not found");
        else
            ans.Add(p.FormatSection(input));
    }

    return String.Join("\n", ans);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM