NickPolyder / NP.ObjectComparison

This repository serves as a library that will make Object Patching and diff easier.
MIT License
2 stars 0 forks source link

Exception on Nullable type #1

Closed codepend closed 2 years ago

codepend commented 2 years ago

On version 0.9.7 After making a few properties on a class nullable, I received the following unhandled exception on checking HasChanges()

There are some null values on some of the properties, though they "construct" okay, but when calling HasChanges it throws the error.

Message: "Expression must be writeable (Parameter 'left')"

Stack Trace: " at System.Linq.Expressions.Expression.RequiresCanWrite(Expression expression, String paramName)\r\n at System.Linq.Expressions.Expression.Assign(Expression left, Expression right)\r\n at NP.ObjectComparison.Analyzers.Infos.ObjectInfoBuilder1.Build(PropertyInfo publicProperty)\r\n at NP.ObjectComparison.Analyzers.Strategies.ObjectAnalyzerBuilderStrategy.Build[TInstance](PropertyInfo propertyInfo, AnalyzerSettings options)\r\n at NP.ObjectComparison.Analyzers.AnalyzerBuilder1.d__0.MoveNext()\r\n at NP.ObjectComparison.Analyzers.ComplexObjectAnalyzer2.Analyze(TInstance originalInstance, TInstance targetInstance)\r\n at NP.ObjectComparison.Analyzers.AnalyzerComposite1.Analyze(TInstance originalInstance, TInstance targetInstance)\r\n at NP.ObjectComparison.ComparisonTracker1.Analyze()\r\n at NP.ObjectComparison.ComparisonTracker1.HasChanges(Boolean autoAnalyze)\r\n at AgreementUpdater.Pages.UpdateByProduct.<>c.b8_0(ComparisonTracker1 x) in C:\\Users\\userProfile\\source\\repos\\Clients\\AgreementUpdater\\AgreementUpdater\\Pages\\UpdateByProduct.razor:line 109\r\n at System.Linq.Enumerable.Any[TSource](IEnumerable1 source, Func`2 predicate)\r\n at AgreementUpdater.Pages.UpdateByProduct.get_isDirty() in C:\Users\userProfile\source\repos\Clients\AgreementUpdater\AgreementUpdater\Pages\UpdateByProduct.razor:line 109\r\n at AgreementUpdater.Pages.UpdateByProduct.BuildRenderTree(RenderTreeBuilder builder) in C:\Users\userProfile\source\repos\Clients\AgreementUpdater\AgreementUpdater\Pages\UpdateByProduct.razor:line 14\r\n at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment)\r\n at Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderInExistingBatch(RenderQueueEntry renderQueueEntry)\r\n at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue()"

Line in question in my code: bool isDirty => additions.Any(x => x.HasChanges(true));

codepend commented 2 years ago

I downloaded the repo and created a simple class and can reproduce. Seems like if the class contains nullable properties it crashes on calling HasChanges().

I just added a class to the WASM sample in the repo

public class ClassWithNullables : ICloneable
{

    public int Id { get; set; }
    public bool? NullableBool { get; set; }
    public double? NullableDouble { get; set; }
    public int? NullableInt { get; set; }
    public string AString { get; set; }

    public object Clone()
    {
        return this.MemberwiseClone();
    }
}

Then in Index.razor Created a property

ComparisonTracker<ClassWithNullables> tracked; 

Updated the CallMe method

void CallMe()
{
    //tracker.Current.Sites.Add("Hello");
    ClassWithNullables myClass = new ClassWithNullables { Id = 1, AString = "asdf", NullableBool = false, NullableDouble = 2.5, 
    NullableInt = 1 };
    tracked = new ComparisonTracker<ClassWithNullables>(myClass);
    var hasChanges = tracked.HasChanges();
    Console.WriteLine("Has Changes: " + hasChanges);
}
NickPolyder commented 2 years ago

I was able to fix it. The code was treating the Nullable properties as complex objects.

See the fix in the commit: 87e1aa36555c65491e80d659e5ae80818d86ca07

It will be in the version 0.9.8