在泛型方法 C# 中处理可为空

handling nullable in generic method C#

我有一个class

  public class ImportAdditionalService
    {
        public string ServiceName { get; set; }
        public decimal? Price { get; set; }
    }

我需要根据 Excel 中的 class 从两列中获取数据,但我的方法使用了泛型 发生异常的地方我突出显示了评论“问题” 方法代码:

   public List<T> GetData<T>(ImportExcelArguments importExcel, out string dataReadingError) where T : new()
        {
            string guid = importExcel.Guid;
            ImportExcelSettings importExcelSettings = importExcel.ImportExcelSettings;
            StringBuilder log = new StringBuilder();
            List<T> result = new List<T>();
            var info = _pendingFileProvider.GetPendingFile(guid);
            var fileStream = GetFile(info.FileGuid);
            var excelLineNumberProperty = typeof(T).GetProperty("ExcelLineNumber");
            IXLWorkbook workbook = new XLWorkbook(fileStream);
            IXLWorksheet worksheet = workbook.Worksheets.Worksheet(1);
            int maxColumn = worksheet.RangeUsed().LastColumn().RangeAddress.LastAddress.ColumnNumber;
            var col = worksheet.RangeUsed().Columns();
            var x = 0;
            var k = 0;
            var u = 0;
            var listInd = new List<int>();
            for (var i = 1; i <= col.Count(); i++)
            {
                IXLCell cell = worksheet.Cell(row: 1, column: i);
                if (cell.Value.ToString().Trim().Length == 0)
                {
                    u++;
                    continue;
                }
                else
                {
                    x++;
                }
                if (x == importExcelSettings.Columns[k].Number)
                {
                    listInd.Add(x + u);
                    k++;
                    if (k == importExcelSettings.Columns.Count)
                        break;
                }
            }
            for (int i = importExcelSettings.StartRow; i <= importExcelSettings.EndRow; i++)
            {
                var row = new T();
                if (excelLineNumberProperty != null)
                {
                    excelLineNumberProperty.SetValue(row, i);
                }
                var indx = 0;
                foreach (var column in importExcelSettings.Columns)
                {
                    PropertyInfo property = row.GetType().GetProperty(column.Caption);
                    var range = worksheet.Cell(i, listInd[indx]);
                    if (range != null)
                    {
                        continue;
                    }

//PROBLEB
                        var value = Convert.ChangeType(range.Value, property.PropertyType, CultureInfo.InvariantCulture);
                        property.SetValue(row, value);
                    indx++;
                }

                if (row is IRawRowDataContainer)
                {
                    var container = row as IRawRowDataContainer;
                    for (int j = Math.Max(1, importExcelSettings.StartColumn); j <= importExcelSettings.EndColumn; j++)
                    {
                        var cell = worksheet.Cell(i, j);
                        if (cell != null)
                        {
                            container.Add(Convert.ToString(cell));
                        }
                        else
                        {
                            var rangeMerg = cell.MergedRange();
                            string value = "";
                            if (rangeMerg != null)
                            {
                                var range = rangeMerg.RangeAddress;
                                value = Convert.ToString(worksheet.Cell(range.FirstAddress).Value);
                            }
                            container.Add(value);
                        }
                    }
                }
                result.Add(row);
            }
            dataReadingError = log.ToString();
            return result;
        }

错误:System.InvalidCastException:“从 'System.Double' 到 'System.Nullable`1[[System.Decimal 的无效转换,mscorlib,版本=4.0.0.0,文化=中性, PublicKeyToken=b77a5c561934e089]]"."

Convert.ChangeType 方法不适用于可为 null 的值类型。您将需要特定代码来处理这些类型 - 例如:

private static object ChangeType(object value, Type targetType)
{
    Type underlyingType = Nullable.GetUnderlyingType(targetType);
    if (underlyingType != null)
    {
        if (value == null) return null;
        targetType = underlyingType;
    }
    
    return Convert.ChangeType(value, targetType, CultureInfo.InvariantCulture);
}

用法:

var value = ChangeType(range.Value, property.PropertyType);
property.SetValue(row, value);