在泛型方法 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);
我有一个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);