以下のコードを使用してクラスの値を設定しています。このクラスの値の一部は次のとおりですstring
decimal
decimal?
int?
。
フィールドのリストがあります-その値を文字列として、.netは以下の例外をスローしています:
System.InvalidCastException : Invalid cast from 'System.String' to 'System.Nullable`1[[System.Decimal, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'.
at System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider)
at System.String.System.IConvertible.ToType(Type type, IFormatProvider provider)
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
at System.Convert.ChangeType(Object value, Type conversionType)
at Surventrix.Domain.Model.Entities.StatisticalData.UpdateStatisticalData(ReportCommit commit, ILogProvider log) in StatisticalData.cs: line 591
at Surventrix.Tests.Stats.StatsTest.CreateStatsFromCommit() in StatsTest.cs: line 32
私のコードは次のとおりです。
public void UpdateStatisticalData(ReportCommit commit, ILogProvider log)
{
var fields = commit.CurrentFieldList.ToList();
var properties = typeof(StatisticalData).GetProperties();
foreach (var p in properties)
{
log.LogMessage("what my name: {0}", p.Name);
// If not writable then cannot null it; if not readable then cannot check it's value
if (!p.CanWrite || !p.CanRead) { continue; }
var mget = p.GetGetMethod(false);
var mset = p.GetSetMethod(false);
// Get and set methods have to be public
if (mget == null) { continue; }
if (mset == null) { continue; }
var val = fields.SingleOrDefault(x => p.Name == x.Name);
if (val == null) continue;
//field.value is stored as a string
if (string.IsNullOrEmpty(val.Value)) continue;
log.LogMessage("set: {0} ----> {1}", p.Name, val.Value);
var typedVal = Convert.ChangeType(val.Value, p.PropertyType);
p.SetValue(this, typedVal, null);
}
}
質問: この例外がスローされないようにコードを修正するにはどうすればよいですか。この例外がここでスローされる理由がよくわかりません...
更新 - ログの結果*
what my name: StatisticalDataID
what my name: OfficeDistanceFromProperty
what my name: OfficeAddress1
set: OfficeAddress1 ----> North Warwickshire House
what my name: OfficeAddress2
set: OfficeAddress2 ----> 92 Wheat Street
what my name: OfficeAddress3
what my name: OfficeCounty
what my name: OfficeTown
set: OfficeTown ----> Nuneaton
what my name: OfficePostcode
set: OfficePostcode ----> CV11 4BH
what my name: ResidentialInternalFloorArea
what my name: ValuationCalculationSqFtAssumed
what my name: SubjectPropertyAddress1
set: SubjectPropertyAddress1 ----> 323 Stanton road
what my name: SubjectPropertyAddress2
set: SubjectPropertyAddress2 ----> cbvcb
what my name: SubjectPropertyAddress3
set: SubjectPropertyAddress3 ----> vcbc
what my name: SubjectPropertyTown
set: SubjectPropertyTown ----> Coventry
what my name: SubjectPropertyCounty
set: SubjectPropertyCounty ----> bcbvc
what my name: SubjectPropertyPostCode
set: SubjectPropertyPostCode ----> CV1 4HH
what my name: OccupierName
set: OccupierName ----> Mr Peters
what my name: AdvanceAmount
set: AdvanceAmount ----> 0
更新- コード @Jon を更新しました。次のようにメソッドを呼び出しています。
var typedVal = NullableSafeChangeType(val.Value, p.PropertyType);
if (!string.IsNullOrEmpty(val.Value))
p.SetValue(this, typedVal, null);
次の場所でエラーがスローされます。
_log.LogMessage("error is here ---> {0}", input);
return input == null || input == "" ? null : Convert.ChangeType(input, underlyingType);
入力は任意の有効な文字列、type(System.String) です。