简体   繁体   中英

Object of type 'System.Int16' cannot be converted to type 'System.Nullable`1[System.Int32]

I've a method that generates list of class type from data of data reader.

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

                        }
                    }

                }

            }

I have class properties, some of them are nullable.

public string StudentName{ get; set; }
public decimal? percentage{ get; set; }
public int? StudentNumber{ get; set; }

Code works properly for all properties except StudentNumber which is int.

In above code following line throws exeption Object of type 'System.Int16' cannot be converted to type 'System.Nullable`1[System.Int32] :

info.SetValue(myobj, (val1 == DBNull.Value) ? null : val1, null);

What can be done to solve this issue?

I don't agree with this code for many reasons but to solve your current problem and answer your question it's because you can't explicitly convert Int16 to Int32 nor to Nullable<Int32> or int? .

To make this happen you need to first convert the value to Int32 then to Nullable<Int3> .

There are better ways but to make it clear what's going on and to fix this one error here you go...

info.SetValue(myobj, val1 == DBNull.Value ? null : (int?)Convert.ToInt32(val1), null);

The problem that you're having here is that, while you can cast a short to an int , you can't cast a boxed short to an int directly. ie,

object box = (short)5;
var x = (int?)box; // Invalid cast.
var y = (int?)(short?)box; // fine, we cast to short and then to int.

You could change the property type of your class to short? , or you could check if your property's type is Nullable<int32> and use Convert.ToInt32 on the value under that situation.

Try to change type:

var val1 = datareader.GetValue(index);    
var convertedValue = (val1 == DBNull.Value) ? null : Convert.ChangeType(val1, info.PropertyType);                            
info.SetValue(myobj, convertedValue, null);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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