如何为Cell类实现支持可空泛型类型的显式转换静态方法?
问题描述
现有Cell类定义
public class Cell { readonly private string? _rawString; public Cell(string inpString) { this._rawString = inpString == "" ? null : inpString; } public static explicit operator DateTime(Cell cell) { DateTime date = DateTime.MinValue; if (DateTime.TryParseExact(cell._rawString, "yyyy/MM/dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out date)) { return date; } else { throw new InvalidCastException($"Cannot convert {cell._rawString} to a date."); } } public static explicit operator DateTime?(Cell cell) { return cell._rawString is null ? null : (DateTime)cell; } public static explicit operator string(Cell cell) { return cell._rawString; } }
需求
希望实现一个静态方法ConvertType<T>,支持如下调用:
string? stringFormat = Cell.ConvertType<string?>(cell); DateTime? dateFormat = Cell.ConvertType<DateTime?>(cell);
尝试的代码及问题
尝试了以下方法,但无法处理可空泛型类型:
public static T TryConvert<T>(Cell cell) { if (cell._rawString is null && typeof(T).IsClass) return default(T); if (typeof(T) == typeof(DateTime)) return (T)(object)(DateTime)cell; if (typeof(T) == typeof(Decimal)) return (T)(object)(Decimal)cell; if (typeof(T) == typeof(int)) return (T)(object)(int)cell; if (typeof(T) == typeof(string)) return (T)(object)(string)cell; // Add more cases for other types as needed throw new InvalidCastException($"Cannot convert {cell._rawString} to {typeof(T)}."); }
解决方案
要支持可空泛型类型,核心是识别并处理可空值类型的基础类型,同时兼容引用类型的可空场景。修改后的代码如下:
public static T ConvertType<T>(Cell cell) { // 处理原始字符串为null的场景 if (cell._rawString is null) { // 可空类型或引用类型直接返回null对应的默认值 if (typeof(T).IsNullableType()) { return default(T); } // 非可空值类型无法转换null,抛出异常 throw new InvalidCastException($"Cannot convert null to non-nullable type {typeof(T)}."); } // 提取实际转换目标类型:如果是可空值类型,取其基础类型 Type targetType = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T); // 执行类型转换 object convertedValue = targetType.Name switch { nameof(DateTime) => (DateTime)cell, nameof(decimal) => decimal.Parse(cell._rawString), // 可根据需求替换为TryParse逻辑 nameof(int) => int.Parse(cell._rawString), // 可根据需求替换为TryParse逻辑 nameof(string) => cell._rawString, // 扩展其他需要支持的类型 _ => throw new InvalidCastException($"Cannot convert {cell._rawString} to {typeof(T)}.") }; // 转换回泛型T并返回 return (T)convertedValue; } // 扩展方法:判断类型是否为可空类型(包括可空值类型和引用类型) private static bool IsNullableType(this Type type) { if (!type.IsValueType) return true; // 引用类型天然可空 return Nullable.GetUnderlyingType(type) != null; // 值类型判断是否为Nullable<T> }
关键修改说明
- null场景处理:针对
_rawString为null的情况,区分可空/非可空类型返回对应结果或抛出异常。 - 可空类型解析:通过
Nullable.GetUnderlyingType提取可空值类型的基础类型,统一复用非可空类型的转换逻辑。 - 辅助判断方法:新增
IsNullableType扩展方法,简化可空类型的判断逻辑。 - 结构化匹配:用switch表达式替代多if判断,代码更简洁易维护。
调用示例
Cell nullCell = new Cell(""); Cell dateCell = new Cell("2024/05/20"); Cell stringCell = new Cell("Hello"); Cell intCell = new Cell("123"); string? strResult = Cell.ConvertType<string?>(nullCell); // 返回null DateTime? dateResult = Cell.ConvertType<DateTime?>(dateCell); // 返回2024-05-20 int? intResult = Cell.ConvertType<int?>(intCell); // 返回123
内容的提问来源于stack exchange,提问作者Rock1432
相关产品推荐
相关产品推荐

