The original UpdateableExpressionProcessor was generating incorrect null comparison logic for value types. It would generate code like:
if (dest.Age == null) // ERROR: Cannot compare value type 'int' to null
dest.Age = new int();This would cause compilation errors because value types cannot be null in C#.
PropertyTypeInfo: Represents type information for a property pathUpdateableTypeContext: Contains type information for all properties in a mapping- Tracks whether properties can be null based on their actual types:
- Value types:
CanBeNull = false - Nullable value types (
int?,DateTime?):CanBeNull = true - Reference types:
CanBeNull = true
- Value types:
TypeAnnotationCollector: Walks the syntax tree and collects type information- Uses
SemanticModelto resolve actual types from syntax nodes - Handles error cases gracefully to prevent source generator failures
- Recursively processes nested object creations and conditional expressions
- Modified to accept
UpdateableTypeContextparameter - Uses type information to generate correct null handling logic:
- Value types: Direct assignment without null checks
- Reference/Nullable types: Proper null checks and else clauses
- Passes
SemanticModeltoEmitHelpers.TryBuildUpdateAssignmentsWithInlining - Enables type collection during code generation
if (dest.Age == null) // COMPILATION ERROR
dest.Age = new int();// For value types - no null check needed
dest.Age = source.Age;
// For reference types - proper null handling
if (source.Person != null)
{
if (dest.Person == null)
dest.Person = new Person();
// ... update properties
}
else
{
dest.Person = null;
}- Value Types:
int,bool,DateTime,decimal- no null checks generated - Reference Types:
string, objects - proper null checks generated - Nullable Value Types:
int?,DateTime?- treated as nullable - Mixed Scenarios: Complex objects with both value and reference type properties
- Backward Compatibility: All existing tests pass
- Correct Code Generation: No more compilation errors for value types
- Type Safety: Proper null handling based on actual types
- Performance: Avoids unnecessary null checks for value types
- Maintainability: Clean, readable generated code
- Backward Compatibility: Existing functionality unchanged
The solution is robust, handles edge cases gracefully, and maintains full backward compatibility while fixing the core issue with value type null handling.