ObjectComparator 3.5.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package ObjectComparator --version 3.5.1
NuGet\Install-Package ObjectComparator -Version 3.5.1
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ObjectComparator" Version="3.5.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add ObjectComparator --version 3.5.1
#r "nuget: ObjectComparator, 3.5.1"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install ObjectComparator as a Cake Addin
#addin nuget:?package=ObjectComparator&version=3.5.1

// Install ObjectComparator as a Cake Tool
#tool nuget:?package=ObjectComparator&version=3.5.1

ObjectComparator

This tool allows comparing objects furthermore provide distinctions. What is more, this tool can set compare rule for certain properties or fields.

NuGet.org Nuget Build status .NET Actions Status

Installation

Install with NuGet Package Manager Console
Install-Package ObjectComparator
Install with .NET CLI
dotnet add package ObjectComparator

Example:

         var actual = new Student
            {
                Name = "Alex",
                Age = 20,
                Vehicle = new Vehicle
                {
                    Model = "Audi"
                },
                Courses = new[]
                {
                    new Course
                    {
                        Name = "Math",
                        Duration = TimeSpan.FromHours(4)
                    },
                    new Course
                    {
                        Name = "Liter",
                        Duration = TimeSpan.FromHours(4)
                    }
                }
            };

            var expected = new Student
            {
                Name = "Bob",
                Age = 20,
                Vehicle = new Vehicle
                {
                    Model = "Opel"
                },
                Courses = new[]
                {
                    new Course
                    {
                        Name = "Math",
                        Duration = TimeSpan.FromHours(3)
                    },
                    new Course
                    {
                        Name = "Literature",
                        Duration = TimeSpan.FromHours(4)
                    }
                }
            };
                
               var result = actual.DeeplyEquals(expected); 
	       
	/*   
	    Path: "Student.Name":
	    Expected Value :Alex
	    Actually Value :Bob
    
	    Path: "Student.Vehicle.Model":
	    Expected Value :Audi
	    Actually Value :Opel
    
	    Path: "Student.Courses[0].Duration":
	    Expected Value :04:00:00
	    Actually Value :03:00:00
    
	    Path: "Student.Courses[1].Name":
	    Expected Value :Liter
	    Actually Value :Literature 
	*/
	    

Set strategies for certain properties/fields

         var result = actual.DeeplyEquals(expected,
                strategy => strategy
                    .Set(x => x.Vehicle.Model, (act, exp) => act.Length == exp.Length)
                    .Set(x => x.Courses[1].Name, (act, exp) => act.StartsWith('L') && exp.StartsWith('L')));  
		    
        /* 
            Path: "Student.Name":
            Expected Value :Alex
            Actually Value :Bob
            
            Path: "Student.Courses[0].Duration":
            Expected Value :04:00:00
            Actually Value :03:00:00
        */
    

Set Ignore list for properties/fields


    var ignore = new[] {"Name", "Courses", "Vehicle" };
    var result = actual.DeeplyEquals(expected,ignore);
   
     /*
     	Objects are deeply equal
    */
    

Display distinctions for properties/fields which have the custom strategy


     var result = actual.DeeplyEquals(expected,
                strategy => strategy
                    .Set(x => x.Vehicle.Model, (act, exp) => act.StartsWith('A') && exp.StartsWith('A')), "Name", "Courses");
		    
    /*
		Path: "Student.Vehicle.Model":
		Expected Value :Audi
		Actually Value :Opel
		Details : (act:(Audi), exp:(Opel)) => (act:(Audi).StartsWith(A) AndAlso exp:(Opel).StartsWith(A))
    */
    
    var skip = new[] {"Vehicle", "Name", "Courses[1].Name"};
            var result = expected.DeeplyEquals(actual,
                str => str.Set(x => x.Courses[0].Duration, (act, exp) => act > TimeSpan.FromHours(3),
                    new Display {Expected = "Expected that Duration should be more that 3 hours"}), skip);
		    
    /*	    
		Path: "Student.Courses[0].Duration":
		Expected Value :Expected that Duration should be more that 3 hours
		Actually Value :04:00:00
		Details : (act:(03:00:00), exp:(04:00:00)) => (act:(03:00:00) > 03:00:00)
   */
  

Display distinctions for Dictionary type


    var expected = new Library
            {
                Books = new Dictionary<string, Book>
                {
                    ["hobbit"] = new Book {Pages = 1000, Text = "hobbit Text"},
                    ["murder in orient express"] = new Book {Pages = 500, Text = "murder in orient express Text"},
                    ["Shantaram"] = new Book {Pages = 500, Text = "Shantaram Text"}
                }
            };

            var actual = new Library
            {
                Books = new Dictionary<string, Book>
                {
                    ["hobbit"] = new Book {Pages = 1, Text = "hobbit Text"},
                    ["murder in orient express"] = new Book {Pages = 500, Text = "murder in orient express Text1"},
                    ["Shantaram"] = new Book {Pages = 500, Text = "Shantaram Text"}
                }
            };

            var result = expected.DeeplyEquals(actual);
	    
    /*
		Path: "Library.Books[hobbit].Pages":
		Expected Value :1000
		Actually Value :1

		Path: "Library.Books[murder in orient express].Text":
		Expected Value :murder in orient express Text
		Actually Value :murder in orient express Text1
   */
  

Set ignore Strategy


     var act = new Student
            {
                Name = "StudentName",
                Age = 1,
                Courses = new[]
                {
                    new Course
                    {
                        Name = "CourseName"
                    }
                }
            };

      var exp = new Student
            {
                Name = "StudentName1",
                Age = 1,
                Courses = new[]
                {
                    new Course
                    {
                        Name = "CourseName1"
                    }
                }
            };

            var distinctions = act.DeeplyEquals(exp, propName => propName.EndsWith("Name"));
    /*
     	Objects are deeply equal
    */
    

DeeplyEquals if type(not primities and not Anonymous Type) has Overridden Equals method


            var actual = new SomeTest("A");
            var expected = new SomeTest("B");
			
			var result = exp.DeeplyEquals(act);
			
	/*
		Path: "SomeTest":
		Expected Value :ObjectsComparator.Tests.SomeTest
		Actually Value :ObjectsComparator.Tests.SomeTest
		Details : Was used override 'Equals()'
	*/
	

DeeplyEquals if type has Overridden Equality method

	/*	
		Path: "SomeTest":
		Expected Value :ObjectsComparator.Tests.SomeTest
		Actually Value :ObjectsComparator.Tests.SomeTest
		Details : == (Equality Operator)
	*/

Display distinctions for Dictionary type

	var firstDictionary = new Dictionary<string, string>
            {
                {"Key", "Value"},
                {"AnotherKey", "Value"},
            };

        var secondDictionary = new Dictionary<string, string>
            {
                {"Key", "Value"},
                {"AnotherKey", "AnotherValue"},
            };
			
	var result = firstDictionary.DeeplyEquals(secondDictionary)
			 
			 
	/*	
		Path: "Dictionary<String, String>[AnotherKey]":
		Expected Value :Value
		Actually Value :AnotherValue
	*/
	

Display distinctions for Anonymous type

            var actual = new {Integer = 1, String = "Test", Nested = new byte[] {1, 2, 3}};
	    var expected = new {Integer = 1, String = "Test", Nested = new byte[] {1, 2, 4}};
			
	    var result = exp.DeeplyEquals(act);
			
	/*
		Path: "AnonymousType<Int32, String, Byte[]>.Nested[2]":
		Expected Value :3
		Actually Value :4
	*/
                
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on ObjectComparator:

Package Downloads
Twileloop.SessionGuard The ID prefix of this package has been reserved for one of the owners of this package by NuGet.org.

Gives you a reactive event based state management framework that centralises application state and give callbacks on state updates across application. It also allows you to write and read persistant states from an XML encoded defalate compressed file, an ideal solution for having data files

Twileloop.SST The ID prefix of this package has been reserved for one of the owners of this package by NuGet.org.

A central state management library with features like state history, diffing, undo, redo, and deep state cloning.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
3.5.8 555 2/12/2024
3.5.7 3,780 10/9/2023
3.5.6 522 9/27/2023
3.5.5 779 9/16/2023
3.5.4 477 9/16/2023
3.5.3 1,491 7/31/2023
3.5.2 16,692 5/16/2022
3.5.1 928 5/14/2022
3.5.0 83,753 4/22/2021
3.4.0 9,853 1/8/2021
3.3.0 975 1/8/2021
3.2.0 946 12/29/2020
3.1.0 1,068 10/6/2020
3.0.0.6 951 5/14/2022
3.0.0 1,233 9/30/2020
2.14.0 973 9/9/2020
2.13.0 1,309 4/15/2020
2.12.0 1,297 12/30/2019
2.11.0 3,928 4/15/2019
2.10.0 1,116 4/9/2019
2.0.9 1,138 3/21/2019
2.0.8 1,236 1/11/2019
2.0.7 1,302 12/15/2018
2.0.6 1,227 11/13/2018
2.0.5 1,218 11/12/2018
2.0.4 1,204 11/12/2018
2.0.3 1,264 11/6/2018

support NET6