简体   繁体   English

在通用方法 C# 中处理可为空的

[英]handling nullable in generic method C#

i have a class我有一个 class

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

I need to get data from two columns in accordance with this class from Excel, but my method uses Generics where the exception occurs I highlighted the comment "PROBLEM" Method code:我需要根据 Excel 中的 class 从两列中获取数据,但是我的方法使用 Generics 发生异常的地方我突出显示了注释“问题”方法代码:

   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;
        }

Error: System.InvalidCastException: "Invalid cast from 'System.Double' to 'System.Nullable`1[[System.Decimal, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"."错误:System.InvalidCastException:“从 'System.Double' 到 'System.Nullable'1 [[System.Decimal, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] 的无效转换。”

The Convert.ChangeType method doesn't work with nullable value types. Convert.ChangeType方法不适用于可为空的值类型。 You will need specific code to handle those types - for example:您将需要特定的代码来处理这些类型 - 例如:

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);
}

Usage:用法:

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

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

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