如何区分null值是System.String或System.Nullable<int>?泛型转换报错求助
Fixing the Invalid Cast Exception in Your Generic Conversion Method
Let's break down why you're hitting those exceptions and fix the method properly:
What's Causing the Issues?
- Wrong Type Handling for Null
arg: Whenargisnull(eitherstringorNullable<int>), your first branch unconditionally converts the string tointand tries to cast it toT. Forstringtype, this fails because you can't cast anintobject directly tostring—that's the "invalid cast" error you're seeing. GetType()Risks for Nullable Types: Ifargis aNullable<int>with no value (HasValue = false), callingarg.GetType()will throw aNullReferenceException. That's because nullable value types get boxed tonullwhen they have no value, so you're trying to call a method on anullobject.- Overreliance on
Convert: UsingConvert.ToInt32orConvert.ToDecimalwill throw exceptions if the string can't be parsed, which makes your method less robust.
Fixed Implementation
Here's a revised version of your method that addresses all these issues:
protected T GetValue<T>(T arg, List<string> item, int index) { // Get the target type, handling nullable types (e.g., int? becomes int) var targetType = typeof(T); var underlyingType = Nullable.GetUnderlyingType(targetType); var effectiveType = underlyingType ?? targetType; // Guard clause: avoid out-of-bounds index access if (index < 0 || index >= item.Count) return default(T); string valueStr = item[index]; // Safely check if arg is null (reference types) or has no value (nullable value types) if (EqualityComparer<T>.Default.Equals(arg, default(T))) { return ConvertValue<T>(valueStr, effectiveType); } // For non-default arg, still convert based on target type return ConvertValue<T>(valueStr, effectiveType); } // Helper method to clean up conversion logic private T ConvertValue<T>(string valueStr, Type effectiveType) { if (effectiveType == typeof(int)) { if (int.TryParse(valueStr, out int intVal)) return (T)(object)intVal; } else if (effectiveType == typeof(string)) { return (T)(object)valueStr; } else if (effectiveType == typeof(decimal)) { if (decimal.TryParse(valueStr, out decimal decVal)) return (T)(object)decVal; } // Return default if conversion fails or type isn't supported return default(T); }
Key Improvements Explained
- Target Type Detection: We use
typeof(T)instead ofarg.GetType()to avoid null reference issues, andNullable.GetUnderlyingTypeto handle nullable value types (likeint?) correctly. - Safe Null/Default Check:
EqualityComparer<T>.Default.Equals(arg, default(T))safely checks ifargisnull(for reference types) or has no value (for nullable value types) without risking exceptions. - Robust Parsing:
TryParsereplacesConvertmethods, so invalid strings won't crash the method—instead, it returns the default value forT. - Cleaner Logic: Extracting conversion to a helper method makes the code easier to read and maintain.
Testing Scenarios
- When
argisstring null: The method returns the raw string fromitem[index]instead of trying to convert it to int. - When
argisNullable<int> null: It parses the string to int (if possible) and returns it as aNullable<int>. - When conversion fails: Returns
default(T)(e.g.,nullfor string,0for int,nullforint?).
内容的提问来源于stack exchange,提问作者jmc
相关产品推荐
相关产品推荐

