“System.Int16”类型的对象无法转换为“System.Nullable”1[System.Int32] 类型
Posted
技术标签:
【中文标题】“System.Int16”类型的对象无法转换为“System.Nullable”1[System.Int32] 类型【英文标题】:Object of type 'System.Int16' cannot be converted to type 'System.Nullable`1[System.Int32] 【发布时间】:2018-06-13 16:38:23 【问题描述】:我有一个从数据读取器的数据生成类类型列表的方法。
if (datareader != null && datareader .HasRows)
Dictionary<string, PropertyInfo> pDict= GetPropertyDictionary<T>();
var fields = GetFieldNames(datareader );
while (datareader .Read())
T myobj= new T();
for (int index = 0; index < fields.Count; index++)
if (pDict.TryGetValue(fields[index], out PropertyInfo info))
var val1 = datareader .GetValue(index);
info.SetValue(myobj, (val1 == DBNull.Value) ? null : val1, null);
我有类属性,其中一些可以为空。
public string StudentName get; set;
public decimal? percentage get; set;
public int? StudentNumber get; set;
代码适用于所有属性,除了 StudentNumber 是 int。
在上面的代码中,以下行抛出异常 “System.Int16”类型的对象无法转换为“System.Nullable`1[System.Int32]”类型:
info.SetValue(myobj, (val1 == DBNull.Value) ? null : val1, null);
有什么办法可以解决这个问题?
【问题讨论】:
(val1 == DBNull.Value) ? null : (int?)val1
是否作为您的三元组工作? val1 的类型是 Int16 且不可为空,因此与第一个表达式中返回 null 设置的类型期望不匹配。
是的,它是三元的。仅当类型为 int? 时,我才会遇到此问题,否则它与小数一起使用?,日期时间?。
Conditional operator assignment with Nullable<value> types?的可能重复
@Priya:你是如何解决这个问题的?在我的情况下,所有类型也使用相同的方法
你好@user2782405。这是数据类型的问题。由于我在这里使用反射,我需要指定读取器从数据库返回的相同数据类型。在数据库中它是 smallint,我试图将它转换为 int。所以它失败了。
【参考方案1】:
出于多种原因,我不同意此代码,但要解决您当前的问题并回答您的问题,这是因为您无法将 Int16
显式转换为 Int32
或 Nullable<Int32>
或 int?
。
要实现这一点,您需要先将值转换为Int32
,然后再转换为Nullable<Int3>
。
有更好的方法,但要弄清楚发生了什么并在这里修复这个错误......
info.SetValue(myobj, val1 == DBNull.Value ? null : (int?)Convert.ToInt32(val1), null);
【讨论】:
但我不能直接使用 (int?) 将其转换为整数。此方法通常用于所有类型,如字符串、整数、小数、日期、双精度等。我只遇到整数问题。 这正是我不同意这段代码的原因。它不能以多种方式使用,但答案只是为了澄清您的问题并修复该错误。 IMO,我相信您需要的是支持并重新考虑该过程,我的意思是我保证的友好。我不怀疑你的技能,所以不要把它当作打击。我只是觉得你想做的事情和你正在做的事情并不一致。此代码假设太多,并没有考虑您想要的通用行为。不过你做得很好,请不要反感地阅读这篇文章,我只是回答了具体问题 @Michale,不,不,我不会以消极的方式接受你的建议。我一定会重新考虑采取的方法,以提高效率。 :) 谢谢伙计。我当然是最好的,我很高兴你没有不高兴。【参考方案2】:您在这里遇到的问题是,虽然您可以将 short
转换为 int
,但您不能将已装箱的 short
直接转换为 int
。即,
object box = (short)5;
var x = (int?)box; // Invalid cast.
var y = (int?)(short?)box; // fine, we cast to short and then to int.
您可以将您的类的属性类型更改为short?
,或者您可以检查您的属性类型是否为Nullable<int32>
,并在这种情况下对值使用Convert.ToInt32
。
【讨论】:
您能提出任何通用的解决方案吗?因为这个方法是为datareader中的每一列调用和执行的 @Priya 我想不出一个好的通用方法。您将不得不编写一些特定于类型的代码来处理特定于类型的转换。 我尝试了一件奇怪的事情,它奏效了。而不是简单的 int?,如果我使用 Int16?,即 public Int16?学生号 得到;放; ,它毫无例外地工作。为什么会这样! @Priya 出于我上面概述的原因。您可以从已装箱的Int16
转换为Int16?
。您不能将已装箱的Int16
转换为Int32
或Int32?
,而必须使用Convert.ToInt32
调用。
好的,好的!谢谢你解释这个! :) 那么我将不得不对我的代码进行一些更改。【参考方案3】:
尝试改变类型:
var val1 = datareader.GetValue(index);
var convertedValue = (val1 == DBNull.Value) ? null : Convert.ChangeType(val1, info.PropertyType);
info.SetValue(myobj, convertedValue, null);
【讨论】:
它给出了另一个错误:System.InvalidCastException: 'Invalid cast from 'System.Int16' to 'System.Nullable`1[[System.Int32,...]] System.InvalidCastException: '从 'System.Int16' 到 'System.Nullable`1[[System.Int32, ]] 的无效转换以上是关于“System.Int16”类型的对象无法转换为“System.Nullable”1[System.Int32] 类型的主要内容,如果未能解决你的问题,请参考以下文章
无法将类型为“System.DateTime”的对象强制转换为类型“System.String”
无法将类型为“System.Collections.Generic.List`1[EPMS.Domain.SingleItem]”的对象强制转换为类型“EPMS
无法将 java.lang.String 类型的对象转换为类型 - FirebaseUI