通过TryParse 或者 TryGetValue 可以判断是否有值

本文介绍了如何在C#中利用float.TryParse方法转换字符串为浮点数,并通过Dictionary<TKey, TValue>.TryGetValue进行字典值的查找。这两种技术在处理数据时能有效避免异常,提高代码的健壮性。示例代码中创建了一个Dictionary<string, int>实例,并尝试获取键为'linch'的值。
 Dictionary<string, int> dic = new Dictionary<string, int>();
    float.TryParse("1236", out float result);
    dic.TryGetValue("linch", out int t);

通过TryParse 或者 TryGetValue 可以判断是否有值

using System; using System.Collections; using System.Collections.Generic; using System.Linq; using TMPro; using UnityEngine; using UnityEngine.UI; using XCharts.Runtime; public class ImportWaterQualityChart : MonoBehaviour { [SerializeField] public XCharts.Runtime.LineChart lineChart; [SerializeField] private Button customButton; [SerializeField] private TMP_InputField startDateInput; [SerializeField] private TMP_InputField startTimeInput; [SerializeField] private TMP_InputField endDateInput; [SerializeField] private TMP_InputField endTimeInput; [SerializeField] private WebDataUpdater webDataUpdater; [SerializeField] private TextMeshProUGUI Tips; [SerializeField] private Button dayButton; // 天按钮(当天24小时) [SerializeField] private Button weekButton; // 周按钮(本周7天) [SerializeField] private Button monthButton; // 月按钮(本月所有天) private bool isCustomDateOnly = false; private TimeRange currentRange = TimeRange.Day; private DateTime customStartTime; private DateTime customEndTime; private List<ImportHourlyData> importHourlyData = new List<ImportHourlyData>(); private Coroutine hideTipsCoroutine; private bool isCustomWithHour = false; public WebDataUpdater WebDataUpdater; private Dictionary<string, string> fieldNameMap = new Dictionary<string, string> { {"W01001_Rtd", "PH"}, //{"W01010_Rtd", "水温"}, {"W21003_Rtd", "氨氮"}, {"W21011_Rtd", "总磷"}, //{"W00000_Rtd", "污水"}, {"W21001_Rtd", "总氮"}, {"W01018_Rtd", "COD"}, {"W00000l_Rtd", "总量"} }; private void Awake() { if (lineChart == null) lineChart = GetComponent<XCharts.Runtime.LineChart>(); DateTime now = DateTime.Now; // 日期输入框默认 startDateInput.text = now.AddDays(-1).ToString("yyyy-MM-dd"); endDateInput.text = now.ToString("yyyy-MM-dd"); // 小时输入框默认 + 提示文本 startTimeInput.text = "22"; startTimeInput.placeholder.GetComponent<TextMeshProUGUI>().text = "输入0-23(可选)"; endTimeInput.text = "14"; endTimeInput.placeholder.GetComponent<TextMeshProUGUI>().text = "输入0-23(可选)"; if (webDataUpdater == null) webDataUpdater = FindObjectOfType<WebDataUpdater>(); // 绑定天/周/月按钮点击事件 if (dayButton != null) dayButton.onClick.AddListener(() => OnTimeRangeButtonClicked(TimeRange.Day)); if (weekButton != null) weekButton.onClick.AddListener(() => OnTimeRangeButtonClicked(TimeRange.Week)); if (monthButton != null) monthButton.onClick.AddListener(() => OnTimeRangeButtonClicked(TimeRange.Month)); if (customButton != null) customButton.onClick.AddListener(() => OnApplyCustomButtonClicked()); } private void OnEnable() { WebDataUpdater.ImportHourlyUpdated += OnImportHourlyDataUpdated; UpdateTimeRange(currentRange); } private void OnDisable() { WebDataUpdater.ImportHourlyUpdated -= OnImportHourlyDataUpdated; } /// 天/周/月按钮点击回调 private void OnTimeRangeButtonClicked(TimeRange targetRange) { currentRange = targetRange; // 更新当前时间范围 UpdateTimeRange(currentRange); // 触发数据请求和图表刷新 ShowTips($"{GetRangeDisplayName(targetRange)}数据加载中..."); // 提示用户 } private string GetRangeDisplayName(TimeRange range) { return range switch { TimeRange.Day => "当天", TimeRange.Week => "本周", TimeRange.Month => "本月", _ => "自定义" }; } private void OnImportHourlyDataUpdated(List<ImportHourlyData> data, string type, string from) { if (type != "between" || from != "import") { return; } importHourlyData = data ?? new List<ImportHourlyData>(); //Debug.Log($"接收主动请求的小时数据量: {importHourlyData.Count} 条"); RefreshChartWithData(); } public void OnApplyCustomButtonClicked() { if (TryParseCustomTimeRange(out DateTime start, out DateTime end, out bool userEnteredTime)) { //Debug.Log($"解析后的自定义时间范围:start={start:yyyy-MM-dd HH:mm:ss}, end={end:yyyy-MM-dd HH:mm:ss}"); customStartTime = start; customEndTime = end; StartCoroutine(WebDataUpdater.GetData(start, end, "between", "import")); currentRange = TimeRange.Custom; } } /// <summary> /// 解析自定义时间输入,优化小时模式处理 /// </summary> private bool TryParseCustomTimeRange(out DateTime start, out DateTime end, out bool userEnteredTime) { start = DateTime.Now; end = DateTime.Now; userEnteredTime = false; isCustomDateOnly = false; isCustomWithHour = false; // 重置标志位 bool hasValidStartHour = false; bool hasValidEndHour = false; try { string startDate = startDateInput.text.Trim(); string startTime = startTimeInput.text.Trim(); string endDate = endDateInput.text.Trim(); string endTime = endTimeInput.text.Trim(); bool hasStartDate = !string.IsNullOrEmpty(startDate); bool hasStartTime = !string.IsNullOrEmpty(startTime); bool hasEndDate = !string.IsNullOrEmpty(endDate); bool hasEndTime = !string.IsNullOrEmpty(endTime); // 处理开始时间(仅小时):新增有效小时判断 if (hasStartTime) { if (startTime.Contains(":")) { startTime = startTime.Split(':')[0].Trim(); startTimeInput.text = startTime; // 更新输入框显示 } if (int.TryParse(startTime, out int startHour) && startHour >= 0 && startHour <= 23) { startTime = $"{startHour:00}:00"; userEnteredTime = true; hasValidStartHour = true; // 标记为“有效小时” } else { ShowTips("开始小时必须是0-23之间的数字"); return false; } } // 处理结束时间(仅小时):新增有效小时判断 if (hasEndTime) { if (endTime.Contains(":")) { endTime = endTime.Split(':')[0].Trim(); endTimeInput.text = endTime; } if (int.TryParse(endTime, out int endHour) && endHour >= 0 && endHour <= 23) { endTime = $"{endHour:00}:00"; userEnteredTime = true; hasValidEndHour = true; // 标记为“有效小时” } else { ShowTips("结束小时必须是0-23之间的数字"); return false; } } isCustomWithHour = hasValidStartHour || hasValidEndHour; // 关键修复:仅当有至少一个有效小时时,才判定为“按小时显示” isCustomDateOnly = hasStartDate && hasEndDate && !isCustomWithHour; // 仅当“有日期+无任何有效小时”时,才判定为“按天显示” // 补全默认时间(无有效小时时,默认当天00:00/23:00) if (hasStartDate && !hasValidStartHour) startTime = "00:00"; if (hasEndDate && !hasValidEndHour) endTime = "23:00"; string startDateTimeStr = string.IsNullOrEmpty(startTime) ? startDate : $"{startDate} {startTime}"; string endDateTimeStr = string.IsNullOrEmpty(endTime) ? endDate : $"{endDate} {endTime}"; if (DateTime.TryParse(startDateTimeStr, out start) && DateTime.TryParse(endDateTimeStr, out end)) { if (end < start) { ShowTips("结束时间不能早于开始时间"); return false; } return true; } } catch (Exception e) { Debug.LogError($"时间解析异常: {e.Message}\n{e.StackTrace}"); } ShowTips("请选择正确的时间范围,例如格式为2025-9-12 18"); return false; } private void ShowTips(string message) { if (Tips == null) return; if (hideTipsCoroutine != null) StopCoroutine(hideTipsCoroutine); Tips.text = message; Tips.gameObject.SetActive(true); hideTipsCoroutine = StartCoroutine(HideTipsAfterDelay(2f)); } private IEnumerator HideTipsAfterDelay(float delay) { yield return new WaitForSeconds(delay); Tips.gameObject.SetActive(false); hideTipsCoroutine = null; } /// <summary> /// 刷新图表 /// </summary> /// <param name="range"></param> private void UpdateTimeRange(TimeRange range) { DateTime start = DateTime.Now; DateTime end = DateTime.Now; switch (range) { case TimeRange.Day: // 当天:00:00到当前时间 start = DateTime.Today; end = DateTime.Now; break; case TimeRange.Week: // 新增:本周逻辑(周一00:00到当前时间) int daysToMonday = (int)DateTime.Now.DayOfWeek - (int)DayOfWeek.Monday; if (daysToMonday < 0) daysToMonday += 7; // 处理周日(转为上周周一) start = DateTime.Today.AddDays(-daysToMonday); // 本周一00:00 end = DateTime.Now; // 当前时间 break; case TimeRange.Month: // 本月:1号00:00到当前时间(自动适配30/31天) start = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1); end = DateTime.Now; break; case TimeRange.Custom: start = customStartTime; end = customEndTime; break; } if (webDataUpdater != null) { StartCoroutine(webDataUpdater.GetData(start, end, "between", "import")); } else { Debug.LogError("WebDataUpdater未赋,请检查引用"); } } /// <summary> /// 获取当前时间范围 /// </summary> private void RefreshChartWithData() { var xAxis = lineChart.EnsureChartComponent<XAxis>(); List<string> labels; if (currentRange == TimeRange.Custom) { labels = GenerateCustomTimeLabels(customStartTime, customEndTime); } else { labels = GenerateTimeLabels(currentRange); } xAxis.data.Clear(); xAxis.data.AddRange(labels); xAxis.axisLabel.SetComponentDirty(); foreach (var serie in lineChart.series) { serie.ClearData(); var fieldName = fieldNameMap.FirstOrDefault(kv => kv.Value == serie.serieName).Key; if (!string.IsNullOrEmpty(fieldName)) { FillSerieWithRealData(serie, labels, fieldName); } else { Debug.LogWarning($"未找到与系列名 {serie.serieName} 匹配的字段,请检查配置"); } } lineChart.RefreshChart(); } /// <summary> /// 填充系列数据 /// </summary> /// <param name="serie"></param> /// <param name="labels"></param> /// <param name="dataField"></param> private void FillSerieWithRealData(Serie serie, List<string> labels, string dataField) { serie.ClearData(); if (importHourlyData.Count > 0) { var firstTime = DateTime.TryParse(importHourlyData[0].create_time, out var ft) ? ft : DateTime.MinValue; var lastTime = DateTime.TryParse(importHourlyData.Last().create_time, out var lt) ? lt : DateTime.MinValue; //Debug.Log($"数据时间范围: {firstTime:yyyy-MM-dd HH:mm} 至 {lastTime:yyyy-MM-dd HH:mm}"); } foreach (var label in labels) { if (DateTime.TryParse(label, out DateTime labelTime)) { var dataPoint = importHourlyData.FirstOrDefault(d => { if (!DateTime.TryParse(d.create_time, out DateTime dataTime)) { Debug.LogWarning($"数据时间格式错误: {d.create_time}"); return false; } // 修复:dataTime <= labelTime.AddHours(1) return dataTime >= labelTime && dataTime <= labelTime.AddHours(1); }); if (dataPoint != null && TryGetDataValue(dataPoint, dataField, out double value)) { serie.AddYData((float)value); //Debug.Log($"匹配成功: {labelTime:HH:mm} 对应: {value}"); } else { serie.AddYData(0f); // Debug.LogWarning($"无匹配数据: {labelTime:yyyy-MM-dd HH:mm}"); } } else { serie.AddYData(0f); Debug.LogWarning($"标签时间解析失败: {label}"); } } } /// <summary> /// 填充指定系列数据 /// </summary> /// <param name="data"></param> /// <param name="fieldName"></param> /// <param name="value"></param> /// <returns></returns> private bool TryGetDataValue(ImportHourlyData data, string fieldName, out double value) { value = 0; string fieldValue = fieldName switch { "W01001_Rtd" => data.W01001_Rtd, //"W01010_Rtd" => data.W01010_Rtd, "W21003_Rtd" => data.W21003_Rtd, "W21011_Rtd" => data.W21011_Rtd, //"W00000_Rtd" => data.W00000_Rtd, "W21001_Rtd" => data.W21001_Rtd, "W01018_Rtd" => data.W01018_Rtd, "W00000l_Rtd" => data.W00000l_Rtd, _ => null }; double.TryParse(fieldValue, out value); return true; } /// <summary> /// 尝试从数据点中获取指定字段的 /// </summary> /// <param name="range"></param> /// <returns></returns> private List<string> GenerateTimeLabels(TimeRange range) { List<string> labels = new List<string>(); DateTime now = DateTime.Now; switch (range) { case TimeRange.Day: // 当天标签:00:00~23:00 for (int hour = 0; hour < 24; hour++) { labels.Add($"{hour:00}:00"); } break; case TimeRange.Week: // 本周标签(仅显示日期,格式:MM-dd) int daysToMonday = (int)now.DayOfWeek - (int)DayOfWeek.Monday; if (daysToMonday < 0) daysToMonday += 7; DateTime monday = now.Date.AddDays(-daysToMonday); for (int i = 0; i < 7; i++) { DateTime currentDay = monday.AddDays(i); labels.Add($"{currentDay:MM-dd}"); // 仅显示月-日,例如:09-19 } break; case TimeRange.Month: // 本月标签:1号~当月最后一天(自动适配30/31天) DateTime firstDayOfMonth = new DateTime(now.Year, now.Month, 1); DateTime lastDayOfMonth = new DateTime(now.Year, now.Month, DateTime.DaysInMonth(now.Year, now.Month)); for (DateTime d = firstDayOfMonth; d <= lastDayOfMonth; d = d.AddDays(1)) { labels.Add($"{d:MM-dd}"); // 格式:09-19 } break; } return labels; } /// <summary> /// 获取指定时间范围内的时间标签 /// </summary> /// <param name="start"></param> /// <param name="end"></param> /// <returns></returns> private List<string> GenerateCustomTimeLabels(DateTime start, DateTime end) { List<string> labels = new List<string>(); TimeSpan span = end - start; // 优化1:用户输入了有效小时 → 强制按小时生成标签(忽略跨度) if (isCustomWithHour) { // 计算从开始到结束的所有小时点(包含开始,不超过结束) DateTime currentHour = new DateTime(start.Year, start.Month, start.Day, start.Hour, 0, 0); while (currentHour <= end) { labels.Add($"{currentHour:yyyy-MM-dd HH:00}"); // 小时级格式:月-日 时:00 currentHour = currentHour.AddHours(1); } } // 优化2:用户未输入小时 → 按时间跨度判断(天/月) else { // 跨度≤31天 → 按天生成标签 if (span.TotalDays <= 31) { DateTime currentDay = start.Date; // 取当天0点 while (currentDay <= end.Date) { labels.Add($"{currentDay:MM-dd}"); // 天级格式:月-日 currentDay = currentDay.AddDays(1); } } // 跨度>31天 → 按月生成标签 else { DateTime currentMonth = new DateTime(start.Year, start.Month, 1); while (currentMonth <= end) { labels.Add($"{currentMonth:yyyy-MM}"); // 月级格式:年-月 currentMonth = currentMonth.AddMonths(1); } } } //Debug.Log($"生成标签数量: {labels.Count}"); if (labels.Count > 0) { //Debug.Log($"标签范围: {labels[0]} 至 {labels.Last()}"); } return labels; } /// <summary> /// 公开接口:获取当前图表的时间标签列表(X轴) /// </summary> /// <returns>时间标签(如“00:00”“09-19”“2025-09”)</returns> public List<string> GetCurrentTimeLabels() { var xAxis = lineChart?.EnsureChartComponent<XAxis>(); return xAxis?.data ?? new List<string>(); } /// <summary> /// 公开接口:获取指定水质指标的数列表 /// </summary> /// <param name="indicatorName">指标名(如“PH”“氨氮”,需与fieldNameMap的一致)</param> /// <returns>数列表(无数据时为0)</returns> public List<float> GetIndicatorData(string indicatorName) { List<float> result = new List<float>(); var timeLabels = GetCurrentTimeLabels(); foreach (var timeLabel in timeLabels) { if (DateTime.TryParse(timeLabel, out DateTime labelTime)) { // 从实际数据中找与 labelTime 匹配的数 float value = FindValueByTimestamp(indicatorName, labelTime); result.Add(value); } else { result.Add(0f); } } return result; } /// <summary> /// 根据时间戳获取指定指标的 /// </summary> /// <param name="indicator"></param> /// <param name="targetTime"></param> /// <returns></returns> private float FindValueByTimestamp(string indicator, DateTime targetTime) { // 从 importHourlyData 中找和 targetTime 匹配的数据 var dataPoint = importHourlyData.FirstOrDefault(d => { if (DateTime.TryParse(d.create_time, out DateTime dataTime)) { return dataTime.Hour == targetTime.Hour; } return false; }); return dataPoint != null ? GetValueFromDataPoint(dataPoint, indicator) : 0f; } /// <summary> /// 公开接口:获取所有需要导出的水质指标名 /// </summary> public List<string> GetExportIndicatorNames() { List<string> allIndicators = new List<string>(); foreach (var indicator in fieldNameMap.Values) { allIndicators.Add(indicator); } return allIndicators; } /// <summary> /// 从数据点中提取指定指标的数(根据fieldNameMap映射关系) /// </summary> /// <param name="dataPoint">实际监测数据点(ImportHourlyData实例)</param> /// <param name="indicatorName">指标名(如"PH")</param> /// <returns>指标数(未找到时返回0)</returns> private float GetValueFromDataPoint(ImportHourlyData dataPoint, string indicatorName) { var fieldEntry = fieldNameMap.FirstOrDefault(kv => kv.Value == indicatorName); if (string.IsNullOrEmpty(fieldEntry.Key)) { Debug.LogWarning($"未找到指标 {indicatorName} 对应的字段映射"); return 0f; } string targetField = fieldEntry.Key; switch (targetField) { case "W01001_Rtd": // PH if (float.TryParse(dataPoint.W01001_Rtd, out float phValue)) return phValue; else return 0f; case "W21003_Rtd": // 氨氮 if (float.TryParse(dataPoint.W21003_Rtd, out float ammoniaValue)) return ammoniaValue; else return 0f; case "W21011_Rtd": // 总磷 if (float.TryParse(dataPoint.W21011_Rtd, out float totalPhosphorusValue)) return totalPhosphorusValue; else return 0f; case "W21001_Rtd": // 总氮 if (float.TryParse(dataPoint.W21001_Rtd, out float totalNitrogenValue)) return totalNitrogenValue; else return 0f; case "W01018_Rtd": // COD if (float.TryParse(dataPoint.W01018_Rtd, out float codValue)) return codValue; else return 0f; case "W00000l_Rtd": // 总量 if (float.TryParse(dataPoint.W00000l_Rtd, out float totalValue)) return totalValue; else return 0f; default: Debug.LogWarning($"未处理的字段 {targetField},请检查fieldNameMap配置"); return 0f; } } public enum TimeRange { Day, Month, Week, Custom } }
最新发布
09-24
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值