Showing preview only (408K chars total). Download the full file or copy to clipboard to get everything.
Repository: ValeraT1982/ObjectsComparer
Branch: master
Commit: b106e48c4679
Files: 126
Total size: 369.9 KB
Directory structure:
gitextract_agfyhd9m/
├── .gitignore
├── LICENSE
├── ObjectsComparer/
│ ├── ObjectsComparer/
│ │ ├── AbstractComparer.cs
│ │ ├── AbstractComparer~1.cs
│ │ ├── Attributes/
│ │ │ └── IgnoreInComparisonAttribute.cs
│ │ ├── BaseComparer.cs
│ │ ├── Comparer.cs
│ │ ├── ComparerOverridesCollection.cs
│ │ ├── ComparersFactory.cs
│ │ ├── Comparer~1.cs
│ │ ├── ComparisonSettings.cs
│ │ ├── CustomComparers/
│ │ │ ├── AbstractDynamicObjectsComprer.cs
│ │ │ ├── AbstractEnumerablesComparer.cs
│ │ │ ├── CompilerGeneratedObjectComparer.cs
│ │ │ ├── DynamicObjectComparer.cs
│ │ │ ├── EnumerablesComparer.cs
│ │ │ ├── EnumerablesComparer~1.cs
│ │ │ ├── ExpandoObjectComparer.cs
│ │ │ ├── GenericEnumerablesComparer.cs
│ │ │ ├── HashSetsComparer.cs
│ │ │ ├── HashSetsComparer~1.cs
│ │ │ ├── IComparerWithCondition.cs
│ │ │ ├── MultidimensionalArrayComparer~1.cs
│ │ │ ├── MultidimensionalArraysComparer.cs
│ │ │ └── TypesComparer.cs
│ │ ├── Difference.cs
│ │ ├── DifferenceTypes.cs
│ │ ├── Exceptions/
│ │ │ ├── AmbiguousComparerOverrideResolutionException.cs
│ │ │ └── ValueComparerExistsException.cs
│ │ ├── IBaseComparer.cs
│ │ ├── IComparer.cs
│ │ ├── IComparersFactory.cs
│ │ ├── IComparer~1.cs
│ │ ├── LICENSE
│ │ ├── ObjectsComparer.csproj
│ │ ├── ObjectsComparer.csproj.DotSettings
│ │ ├── Properties/
│ │ │ └── AssemblyInfo.cs
│ │ ├── Utils/
│ │ │ ├── MemberInfoExtensions.cs
│ │ │ ├── PropertyHelper.cs
│ │ │ └── TypeExtensions.cs
│ │ └── ValueComparers/
│ │ ├── AbstractValueComparer.cs
│ │ ├── AbstractValueComparer~1.cs
│ │ ├── DefaultValueComparer.cs
│ │ ├── DefaultValueValueComparer.cs
│ │ ├── DoNotCompareValueComparer.cs
│ │ ├── DynamicValueComparer.cs
│ │ ├── IValueComparer.cs
│ │ ├── IValueComparer~1.cs
│ │ ├── IgnoreCaseStringsValueComparer.cs
│ │ ├── NulableStringsValueComparer.cs
│ │ ├── ToStringComparer.cs
│ │ └── UriComparer.cs
│ ├── ObjectsComparer.Examples/
│ │ ├── BasicExamples/
│ │ │ ├── BasicExampleTests.cs
│ │ │ └── ClassA.cs
│ │ ├── Example1/
│ │ │ ├── Error.cs
│ │ │ ├── Example1Tests.cs
│ │ │ └── Message.cs
│ │ ├── Example2/
│ │ │ ├── Example2Tests.cs
│ │ │ ├── MyComparersFactory.cs
│ │ │ ├── Person.cs
│ │ │ └── PhoneNumberComparer.cs
│ │ ├── Example3/
│ │ │ ├── Example3Tests.cs
│ │ │ ├── Settings0.json
│ │ │ ├── Settings1.json
│ │ │ └── Settings2.json
│ │ ├── Example4/
│ │ │ ├── CustomFormulaItemsComparer.cs
│ │ │ ├── Example4Tests.cs
│ │ │ ├── Formula.cs
│ │ │ ├── FormulaItem.cs
│ │ │ └── MyComparersFactory.cs
│ │ ├── Example5/
│ │ │ ├── Error.cs
│ │ │ ├── Example5Tests.cs
│ │ │ └── IgnoreAttribute.cs
│ │ ├── ObjectsComparer.Examples.csproj
│ │ └── OutputHelper.cs
│ ├── ObjectsComparer.Tests/
│ │ ├── AbstractComparerGenericTests.cs
│ │ ├── AbstractComparerTests.cs
│ │ ├── ComparerNonGenericTests.cs
│ │ ├── ComparerOverridesCollectionTests.cs
│ │ ├── ComparerTests.cs
│ │ ├── Comparer_CompilerGeneratedObjectsTests.cs
│ │ ├── Comparer_DynamicObjectsTests.cs
│ │ ├── Comparer_ExpandoObjectsTests.cs
│ │ ├── Comparer_GenericEnumerableTests.cs
│ │ ├── Comparer_IPEndPointTests.cs
│ │ ├── Comparer_Issue24Tests.cs
│ │ ├── Comparer_MultidimensionalArraysTests.cs
│ │ ├── Comparer_NonGenericEnumerableTests.cs
│ │ ├── Comparer_OverridesTests.cs
│ │ ├── Comparer_StringBuilderTests.cs
│ │ ├── Comparer_UriTests.cs
│ │ ├── ComparersFactoryTests.cs
│ │ ├── ComparisonSettingsTests.cs
│ │ ├── CustomComparers/
│ │ │ ├── AbstractValueComparerTests.cs
│ │ │ ├── DynamicValueComparerTests.cs
│ │ │ ├── EnumerablesComparerGenericTests.cs
│ │ │ ├── EnumerablesComparerTests.cs
│ │ │ ├── HashSetsComparerTests.cs
│ │ │ └── TypesComparerTests.cs
│ │ ├── DifferenceTests.cs
│ │ ├── ObjectsComparer.Tests.csproj
│ │ ├── ObjectsComparer.Tests.csproj.DotSettings
│ │ ├── ParentInterfacePropertiesTests.cs
│ │ ├── TestClasses/
│ │ │ ├── A.cs
│ │ │ ├── B.cs
│ │ │ ├── Child.cs
│ │ │ ├── CollectionOfB.cs
│ │ │ ├── EnumerableImplementation.cs
│ │ │ ├── FlagsEnum.cs
│ │ │ ├── ITestInterface.cs
│ │ │ ├── InheritedFromB.cs
│ │ │ ├── MultidimensionalArrays.cs
│ │ │ ├── Parent.cs
│ │ │ ├── ParentChild.cs
│ │ │ ├── TestEnum.cs
│ │ │ ├── TestInterfaceImplementation1.cs
│ │ │ ├── TestInterfaceImplementation2.cs
│ │ │ └── TestStruct.cs
│ │ ├── Utils/
│ │ │ └── TypeExtensionsTests.cs
│ │ └── ValueComparers/
│ │ ├── DefaultValueComparerTests.cs
│ │ ├── DefaultValueValueComparerTests.cs
│ │ ├── DoNotCompareValueComparerTests.cs
│ │ ├── IgnoreCaseStringsValueComparerTests.cs
│ │ └── NulableStringsValueComparerTests.cs
│ └── ObjectsComparer.sln
└── README.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2019 Valerii Tereshchenko
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: ObjectsComparer/ObjectsComparer/AbstractComparer.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
namespace ObjectsComparer
{
/// <summary>
/// Implementation of <see cref="T:ObjectsComparer.IComparer" /> which provides implementation of Compare methods.
/// </summary>
public abstract class AbstractComparer: BaseComparer, IComparer
{
protected AbstractComparer(ComparisonSettings settings, BaseComparer parentComparer, IComparersFactory factory)
: base(settings, parentComparer, factory)
{
}
public abstract IEnumerable<Difference> CalculateDifferences(Type type, object obj1, object obj2);
/// <summary>
/// Calculates list of differences between objects.
/// </summary>
/// <typeparam name="T">Type.</typeparam>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <returns>List of differences between objects.</returns>
public IEnumerable<Difference> CalculateDifferences<T>(T obj1, T obj2)
{
return CalculateDifferences(typeof(T), obj1, obj2);
}
/// <summary>
/// Compares objects.
/// </summary>
/// <param name="type">Type.</param>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <param name="differences">List of differences.</param>
/// <returns>True if objects are equal, otherwise false.</returns>
public bool Compare(Type type, object obj1, object obj2, out IEnumerable<Difference> differences)
{
differences = CalculateDifferences(type, obj1, obj2);
return !differences.Any();
}
/// <summary>
/// Compares objects.
/// </summary>
/// <param name="type">Type.</param>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <returns>True if objects are equal, otherwise false.</returns>
public bool Compare(Type type, object obj1, object obj2)
{
return !CalculateDifferences(type, obj1, obj2).Any();
}
/// <summary>
/// Compares objects.
/// </summary>
/// <typeparam name="T">Type.</typeparam>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <param name="differences">List of differences.</param>
/// <returns>True if objects are equal, otherwise false.</returns>
public bool Compare<T>(T obj1, T obj2, out IEnumerable<Difference> differences)
{
return Compare(typeof(T), obj1, obj2, out differences);
}
/// <summary>
/// Compares objects.
/// </summary>
/// <typeparam name="T">Type.</typeparam>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <returns>True if objects are equal, otherwise false.</returns>
public bool Compare<T>(T obj1, T obj2)
{
return Compare(typeof(T), obj1, obj2);
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/AbstractComparer~1.cs
================================================
using System.Collections.Generic;
using System.Linq;
namespace ObjectsComparer
{
/// <summary>
/// Implementation of <see cref="IComparer{T}"/> which provides implementation of Compare methods.
/// </summary>
public abstract class AbstractComparer<T>: BaseComparer, IComparer<T>
{
protected AbstractComparer(ComparisonSettings settings, BaseComparer parentComparer, IComparersFactory factory)
:base(settings, parentComparer, factory)
{
}
/// <summary>
/// Compares objects.
/// </summary>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <param name="differences">List of differences.</param>
/// <returns>True if objects are equal, otherwise false.</returns>
public bool Compare(T obj1, T obj2, out IEnumerable<Difference> differences)
{
differences = CalculateDifferences(obj1, obj2);
return !differences.Any();
}
/// <summary>
/// Compares objects.
/// </summary>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <returns>True if objects are equal, otherwise false.</returns>
public bool Compare(T obj1, T obj2)
{
return !CalculateDifferences(obj1, obj2).Any();
}
/// <summary>
/// Calculates list of differences between objects.
/// </summary>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <returns>List of differences between objects.</returns>
public abstract IEnumerable<Difference> CalculateDifferences(T obj1, T obj2);
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/Attributes/IgnoreInComparisonAttribute.cs
================================================
// ***********************************************************************
// Assembly : Objects Comparer
// Author : Ankur Kumar Gupta
// Created : 24-Feb-2022
// ***********************************************************************
namespace ObjectsComparer.Attributes
{
using System;
/// <summary>
/// Class is used to specify whether the element on which it is applied will have comparison effect
/// </summary>
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public sealed class IgnoreInComparisonAttribute : Attribute
{
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/BaseComparer.cs
================================================
using System;
using System.Linq.Expressions;
using System.Reflection;
using ObjectsComparer.Utils;
namespace ObjectsComparer
{
/// <summary>
/// Provides base implementation to configure comparer.
/// </summary>
public abstract class BaseComparer: IBaseComparer
{
/// <summary>
/// Comparison Settings.
/// </summary>
public ComparisonSettings Settings { get; }
/// <summary>
/// Default <see cref="IValueComparer"/>
/// </summary>
public IValueComparer DefaultValueComparer { get; private set; }
protected IComparersFactory Factory { get; }
internal ComparerOverridesCollection OverridesCollection { get; } = new ComparerOverridesCollection();
protected BaseComparer(ComparisonSettings settings, BaseComparer parentComparer, IComparersFactory factory)
{
Factory = factory ?? new ComparersFactory();
Settings = settings ?? new ComparisonSettings();
DefaultValueComparer = new DefaultValueComparer();
// ReSharper disable once InvertIf
if (parentComparer != null)
{
DefaultValueComparer = parentComparer.DefaultValueComparer;
OverridesCollection.Merge(parentComparer.OverridesCollection);
}
}
/// <summary>
/// Adds Comparer Override by Type.
/// </summary>
/// <param name="type">Type.</param>
/// <param name="valueComparer">Value Comparer.</param>
/// <param name="filter">Value Comparer will be used only if filter(memberInfo) == true. Null by default.</param>
public void AddComparerOverride(Type type, IValueComparer valueComparer, Func<MemberInfo, bool> filter = null)
{
OverridesCollection.AddComparer(type, valueComparer, filter);
}
/// <summary>
/// Adds Comparer Override by member filter.
/// </summary>
/// <param name="valueComparer">Value Comparer.</param>
/// <param name="filter">Value Comparer will be used only if filter(memberInfo) == true.</param>
public void AddComparerOverride(IValueComparer valueComparer, Func<MemberInfo, bool> filter)
{
OverridesCollection.AddComparer(valueComparer, filter);
}
/// <summary>
/// Adds Comparer Override by Type.
/// </summary>
/// <typeparam name="TType">Type.</typeparam>
/// <param name="valueComparer">Value Comparer.</param>
/// <param name="filter">Value Comparer will be used only if filter(memberInfo) == true. Null by default.</param>
public void AddComparerOverride<TType>(IValueComparer valueComparer, Func<MemberInfo, bool> filter = null)
{
AddComparerOverride(typeof(TType), valueComparer, filter);
}
/// <summary>
/// Adds Comparer Override by Member.
/// </summary>
/// <typeparam name="TProp">Type of the member.</typeparam>
/// <param name="memberLambda">Lambda to get member.</param>
/// <param name="valueComparer">Value Comparer.</param>
public void AddComparerOverride<TProp>(Expression<Func<TProp>> memberLambda, IValueComparer valueComparer)
{
OverridesCollection.AddComparer(PropertyHelper.GetMemberInfo(memberLambda), valueComparer);
}
/// <summary>
/// Adds Comparer Override by Member.
/// </summary>
/// <typeparam name="TProp">Type of the member.</typeparam>
/// <param name="memberLambda">Lambda to get member.</param>
/// <param name="compareFunction">Function to compare objects.</param>
/// <param name="toStringFunction">Function to convert objects to string.</param>
public void AddComparerOverride<TProp>(
Expression<Func<TProp>> memberLambda,
Func<TProp, TProp, ComparisonSettings, bool> compareFunction,
Func<TProp, string> toStringFunction)
{
OverridesCollection.AddComparer(
PropertyHelper.GetMemberInfo(memberLambda),
new DynamicValueComparer<TProp>(
compareFunction,
toStringFunction));
}
/// <summary>
/// Adds Comparer Override by Member.
/// </summary>
/// <typeparam name="TProp">Type of the member.</typeparam>
/// <param name="memberLambda">Lambda to get member.</param>
/// <param name="compareFunction">Function to compare objects.</param>
public void AddComparerOverride<TProp>(
Expression<Func<TProp>> memberLambda,
Func<TProp, TProp, ComparisonSettings, bool> compareFunction)
{
OverridesCollection.AddComparer(
PropertyHelper.GetMemberInfo(memberLambda),
new DynamicValueComparer<TProp>(
compareFunction,
obj => obj?.ToString()));
}
/// <summary>
/// Adds Comparer Override by Member.
/// </summary>
/// <param name="memberInfo">Member Info.</param>
/// <param name="valueComparer">Value Comparer.</param>
public void AddComparerOverride(MemberInfo memberInfo, IValueComparer valueComparer)
{
OverridesCollection.AddComparer(memberInfo, valueComparer);
}
/// <summary>
/// Adds Comparer Override by Member name.
/// </summary>
/// <param name="memberName">Member Name.</param>
/// <param name="valueComparer">Value Comparer.</param>
/// <param name="filter">Value Comparer will be used only if filter(memberInfo) == true. Null by default.</param>
public void AddComparerOverride(string memberName, IValueComparer valueComparer, Func<MemberInfo, bool> filter = null)
{
OverridesCollection.AddComparer(memberName, valueComparer, filter);
}
/// <summary>
/// Sets <see cref="IBaseComparer.DefaultValueComparer"/>.
/// </summary>
/// <param name="valueComparer">Value Comparer.</param>
public void SetDefaultComparer(IValueComparer valueComparer)
{
DefaultValueComparer = valueComparer ?? throw new ArgumentNullException(nameof(valueComparer));
}
/// <summary>
/// Ignors comparison for Type.
/// </summary>
/// <typeparam name="TType">Type.</typeparam>
public void IgnoreMember<TType>()
{
OverridesCollection.AddComparer(typeof(TType), DoNotCompareValueComparer.Instance);
}
/// <summary>
/// Ignors comparison for Member.
/// </summary>
/// <typeparam name="TProp">Type of the member.</typeparam>
public void IgnoreMember<TProp>(Expression<Func<TProp>> memberLambda)
{
OverridesCollection.AddComparer(
PropertyHelper.GetMemberInfo(memberLambda),
DoNotCompareValueComparer.Instance);
}
/// <summary>
/// Ignors comparison for Member by Member name.
/// </summary>
/// <param name="memberName">Member Name.</param>
public void IgnoreMember(string memberName)
{
OverridesCollection.AddComparer(memberName, DoNotCompareValueComparer.Instance);
}
/// <summary>
/// Ignors comparison by Member filter.
/// </summary>
/// <param name="filter">Member will be ignored if filter(memberInfo) == true.</param>
public void IgnoreMember(Func<MemberInfo, bool> filter)
{
OverridesCollection.AddComparer(DoNotCompareValueComparer.Instance, filter);
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/Comparer.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using ObjectsComparer.Utils;
namespace ObjectsComparer
{
/// <summary>
/// Compares objects.
/// </summary>
public class Comparer : AbstractComparer
{
private static string CalculateDifferencesMethodName
{
// ReSharper disable once IteratorMethodResultIsIgnored
get { return MemberInfoExtensions.GetMethodName<Comparer<object>>(x => x.CalculateDifferences(null, null)); }
}
/// <summary>
/// Initializes a new instance of the <see cref="Comparer" /> class.
/// </summary>
/// <param name="settings">Comparison Settings.</param>
/// <param name="parentComparer">Parent Comparer. Is used to copy DefaultValueComparer and Overrides. Null by default.</param>
/// <param name="factory">Factory to create comparers in case of some members of the objects will need it.</param>
public Comparer(ComparisonSettings settings = null, BaseComparer parentComparer = null, IComparersFactory factory = null) : base(settings, parentComparer, factory)
{
}
/// <summary>
/// Calculates list of differences between objects.
/// </summary>
/// <param name="type">Type.</param>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <returns>List of differences between objects.</returns>
public override IEnumerable<Difference> CalculateDifferences(Type type, object obj1, object obj2)
{
var objectsComparerMethod = typeof(IComparersFactory).GetTypeInfo().GetMethods().First(m => m.IsGenericMethod);
var objectsComparerGenericMethod = objectsComparerMethod.MakeGenericMethod(type);
var comparer = objectsComparerGenericMethod.Invoke(Factory, new object[] { Settings, this });
var genericType = typeof(IComparer<>).MakeGenericType(type);
var method = genericType.GetTypeInfo().GetMethod(CalculateDifferencesMethodName, new[] { type, type });
// ReSharper disable once PossibleNullReferenceException
return (IEnumerable<Difference>)method.Invoke(comparer, new[] { obj1, obj2 });
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/ComparerOverridesCollection.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using ObjectsComparer.Exceptions;
using ObjectsComparer.Utils;
namespace ObjectsComparer
{
internal class ComparerOverridesCollection
{
private class ValueComparerWithFilter
{
public IValueComparer ValueComparer { get; }
public Func<MemberInfo, bool> Filter { get; }
public ValueComparerWithFilter(IValueComparer valueComparer, Func<MemberInfo, bool> filter)
{
Filter = filter;
ValueComparer = valueComparer;
}
}
private readonly List<Tuple<Func<MemberInfo, bool>, IValueComparer>> _overridesByMemberFilter = new List<Tuple<Func<MemberInfo, bool>, IValueComparer>>();
private readonly Dictionary<MemberInfo, IValueComparer> _overridesByMember = new Dictionary<MemberInfo, IValueComparer>();
private readonly Dictionary<Type, List<ValueComparerWithFilter>> _overridesByType = new Dictionary<Type, List<ValueComparerWithFilter>>();
private readonly Dictionary<string, List<ValueComparerWithFilter>> _overridesByName = new Dictionary<string, List<ValueComparerWithFilter>>();
public void AddComparer(MemberInfo memberInfo, IValueComparer valueComparer)
{
if (memberInfo == null)
{
throw new ArgumentNullException(nameof(memberInfo));
}
if (_overridesByMember.ContainsKey(memberInfo))
{
throw new ValueComparerExistsException(memberInfo);
}
_overridesByMember[memberInfo] = valueComparer ?? throw new ArgumentNullException(nameof(valueComparer));
}
public void AddComparer(IValueComparer valueComparer, Func<MemberInfo, bool> filter)
{
if (filter == null)
{
throw new ArgumentNullException(nameof(filter));
}
_overridesByMemberFilter.Add(new Tuple<Func<MemberInfo, bool>, IValueComparer>(filter, valueComparer));
}
public void AddComparer(Type type, IValueComparer valueComparer,
Func<MemberInfo, bool> filter = null)
{
if (type == null)
{
throw new ArgumentNullException(nameof(type));
}
if (valueComparer == null)
{
throw new ArgumentNullException(nameof(valueComparer));
}
if (!_overridesByType.ContainsKey(type))
{
_overridesByType[type] = new List<ValueComparerWithFilter>();
}
if (!_overridesByType[type].Any(comparer => comparer.ValueComparer == valueComparer && comparer.Filter == filter))
{
_overridesByType[type].Add(new ValueComparerWithFilter(valueComparer, filter));
}
}
public void AddComparer(string memberName, IValueComparer valueComparer,
Func<MemberInfo, bool> filter = null)
{
if (string.IsNullOrWhiteSpace(memberName))
{
throw new ArgumentException($"{nameof(memberName)} cannot be null or empty");
}
if (valueComparer == null)
{
throw new ArgumentNullException(nameof(valueComparer));
}
if (!_overridesByName.ContainsKey(memberName))
{
_overridesByName[memberName] = new List<ValueComparerWithFilter>();
}
_overridesByName[memberName].Add(new ValueComparerWithFilter(valueComparer, filter));
}
public void Merge(ComparerOverridesCollection collection)
{
foreach (var overridePair in collection._overridesByMember)
{
AddComparer(overridePair.Key, overridePair.Value);
}
foreach (var overrideCollection in collection._overridesByType)
{
foreach (var overridePair in overrideCollection.Value)
{
AddComparer(overrideCollection.Key, overridePair.ValueComparer, overridePair.Filter);
}
}
foreach (var overrideCollection in collection._overridesByName)
{
foreach (var overridePair in overrideCollection.Value)
{
AddComparer(overrideCollection.Key, overridePair.ValueComparer, overridePair.Filter);
}
}
foreach (var memberFilterOverride in collection._overridesByMemberFilter)
{
AddComparer(memberFilterOverride.Item2, memberFilterOverride.Item1);
}
}
public IValueComparer GetComparer(Type type)
{
if (type == null)
{
throw new ArgumentNullException(nameof(type));
}
if (!_overridesByType.TryGetValue(type, out var overridesByType))
{
return null;
}
overridesByType = overridesByType.Where(o => o.Filter == null).ToList();
if (overridesByType.Count > 1)
{
throw new AmbiguousComparerOverrideResolutionException(type);
}
return overridesByType.Count == 1 ? overridesByType[0].ValueComparer : null;
}
public IValueComparer GetComparer(MemberInfo memberInfo)
{
if (memberInfo == null)
{
throw new ArgumentNullException(nameof(memberInfo));
}
if (_overridesByMember.TryGetValue(memberInfo, out var overrideByMemberInfo))
{
return overrideByMemberInfo;
}
var memberFilterOverride = _overridesByMemberFilter.Find(t => t.Item1(memberInfo))?.Item2;
if (memberFilterOverride != null)
{
return memberFilterOverride;
}
if (_overridesByName.TryGetValue(memberInfo.Name, out var overridesByName))
{
overridesByName = overridesByName.Where(o => o.Filter == null || o.Filter(memberInfo)).ToList();
if (overridesByName.Count > 1)
{
throw new AmbiguousComparerOverrideResolutionException(memberInfo);
}
if (overridesByName.Count == 1)
{
return overridesByName[0].ValueComparer;
}
}
if (_overridesByType.TryGetValue(memberInfo.GetMemberType(), out var overridesByType))
{
overridesByType = overridesByType.Where(o => o.Filter == null || o.Filter(memberInfo)).ToList();
if (overridesByType.Count > 1)
{
throw new AmbiguousComparerOverrideResolutionException(memberInfo);
}
if (overridesByType.Count == 1)
{
return overridesByType[0].ValueComparer;
}
}
return null;
}
public IValueComparer GetComparer(string memberName)
{
if (string.IsNullOrWhiteSpace(memberName))
{
throw new ArgumentNullException(nameof(memberName));
}
if (!_overridesByName.TryGetValue(memberName, out var overridesByName))
{
return null;
}
overridesByName = overridesByName.Where(o => o.Filter == null).ToList();
if (overridesByName.Count > 1)
{
throw new AmbiguousComparerOverrideResolutionException(memberName);
}
return overridesByName.Count == 1 ? overridesByName[0].ValueComparer : null;
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/ComparersFactory.cs
================================================
using System;
namespace ObjectsComparer
{
/// <summary>
/// Implements Comparers Factory.
/// </summary>
public class ComparersFactory : IComparersFactory
{
/// <summary>
/// Creates type specific comparer.
/// </summary>
/// <typeparam name="T">Type.</typeparam>
/// <param name="settings">Comparison Settings. Null by default.</param>
/// <param name="parentComparer">Parent comparer. Null by default.</param>
/// <returns>Instance of <see cref="IComparer{T}"/>.</returns>
public virtual IComparer<T> GetObjectsComparer<T>(ComparisonSettings settings = null, BaseComparer parentComparer = null)
{
return new Comparer<T>(settings, parentComparer, this);
}
/// <summary>
/// Creates type specific comparer.
/// </summary>
/// <param name="type">Type.</param>
/// <param name="settings">Comparison Settings. Null by default.</param>
/// <param name="parentComparer">Parent comparer. Null by default.</param>
/// <returns>Instance of <see cref="IComparer"/>.</returns>
public IComparer GetObjectsComparer(Type type, ComparisonSettings settings = null, BaseComparer parentComparer = null)
{
return new Comparer(settings, parentComparer, this);
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/Comparer~1.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using ObjectsComparer.Utils;
using ObjectsComparer.Attributes;
namespace ObjectsComparer
{
/// <summary>
/// Compares objects of type <see cref="T"/>.
/// </summary>
public class Comparer<T> : AbstractComparer<T>
{
private readonly List<MemberInfo> _members;
private readonly List<IComparerWithCondition> _conditionalComparers;
/// <summary>
/// Initializes a new instance of the <see cref="Comparer{T}" /> class.
/// </summary>
/// <param name="settings">Comparison Settings.</param>
/// <param name="parentComparer">Parent Comparer. Is used to copy DefaultValueComparer and Overrides. Null by default.</param>
/// <param name="factory">Factory to create comparers in case of some members of the objects will need it.</param>
public Comparer(ComparisonSettings settings = null, BaseComparer parentComparer = null, IComparersFactory factory = null)
: base(settings, parentComparer, factory)
{
var properties = GetProperties(typeof(T), new List<Type>());
var fields = typeof(T).GetTypeInfo().GetFields().Where(f =>
f.IsPublic
&& !f.IsStatic
&& !f.GetCustomAttributes(true).Any(c=> c is IgnoreInComparisonAttribute)).ToList();
_members = properties.Union(fields.Cast<MemberInfo>()).ToList();
_conditionalComparers = new List<IComparerWithCondition>
{
new MultidimensionalArraysComparer(Settings, this, Factory),
new ExpandoObjectComparer(Settings, this, Factory),
new DynamicObjectComparer(Settings, this, Factory),
new CompilerGeneratedObjectComparer(Settings, this, Factory),
new HashSetsComparer(Settings, this, Factory),
new GenericEnumerablesComparer(Settings, this, Factory),
new EnumerablesComparer(Settings, this, Factory),
new TypesComparer(Settings, this, Factory)
};
// Additional value comparers
AddComparerOverride<StringBuilder>(new ToStringComparer<StringBuilder>());
AddComparerOverride<Uri>(UriComparer.Instance);
}
/// <summary>
/// Calculates list of differences between objects.
/// </summary>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <returns>List of differences between objects.</returns>
public override IEnumerable<Difference> CalculateDifferences(T obj1, T obj2)
{
return CalculateDifferences(obj1, obj2, null);
}
internal IEnumerable<Difference> CalculateDifferences(T obj1, T obj2, MemberInfo memberInfo)
{
var comparer = memberInfo != null
? OverridesCollection.GetComparer(memberInfo)
: OverridesCollection.GetComparer(typeof(T));
if (typeof(T).IsComparable() ||
comparer != null)
{
comparer = comparer ?? DefaultValueComparer;
if (!comparer.Compare(obj1, obj2, Settings))
{
yield return
new Difference(string.Empty, comparer.ToString(obj1),
comparer.ToString(obj2));
}
yield break;
}
var conditionalComparer = _conditionalComparers.FirstOrDefault(c => c.IsMatch(typeof(T), obj1, obj2));
if (conditionalComparer != null)
{
foreach (var difference in conditionalComparer.CalculateDifferences(typeof(T), obj1, obj2))
{
yield return difference;
}
if (conditionalComparer.IsStopComparison(typeof(T), obj1, obj2))
{
yield break;
}
}
if (obj1 == null || obj2 == null)
{
if (!DefaultValueComparer.Compare(obj1, obj2, Settings))
{
yield return new Difference(string.Empty, DefaultValueComparer.ToString(obj1), DefaultValueComparer.ToString(obj2));
}
yield break;
}
if (!Settings.RecursiveComparison)
{
yield break;
}
foreach (var member in _members)
{
if (member.GetCustomAttributes(true).Any(c => c is IgnoreInComparisonAttribute))
{
continue;
}
var value1 = member.GetMemberValue(obj1);
var value2 = member.GetMemberValue(obj2);
var type = member.GetMemberType();
if (conditionalComparer != null && conditionalComparer.SkipMember(typeof(T), member))
{
continue;
}
var valueComparer = DefaultValueComparer;
var hasCustomComparer = false;
var comparerOverride = OverridesCollection.GetComparer(member);
if (comparerOverride != null)
{
valueComparer = comparerOverride;
hasCustomComparer = true;
}
if (!hasCustomComparer
&& !type.IsComparable())
{
var objectDataComparer = Factory.GetObjectsComparer(type, Settings, this);
foreach (var failure in objectDataComparer.CalculateDifferences(type, value1, value2))
{
yield return failure.InsertPath(member.Name);
}
continue;
}
if (!valueComparer.Compare(value1, value2, Settings))
{
yield return new Difference(member.Name, valueComparer.ToString(value1), valueComparer.ToString(value2));
}
}
}
private List<PropertyInfo> GetProperties(Type type, List<Type> processedTypes)
{
var properties = type.GetTypeInfo().GetProperties().Where(p =>
p.CanRead
&& p.GetGetMethod(true).IsPublic
&& p.GetGetMethod(true).GetParameters().Length == 0
&& !p.GetCustomAttributes(true).Any(c=> c is IgnoreInComparisonAttribute)
&& !p.GetGetMethod(true).IsStatic).ToList();
processedTypes.Add(type);
if (type.GetTypeInfo().IsInterface)
{
foreach (var parrentInterface in type.GetTypeInfo().GetInterfaces())
{
if (processedTypes.Contains(parrentInterface))
{
continue;
}
properties = properties
.Union(GetProperties(parrentInterface, processedTypes))
.Distinct()
.ToList();
}
}
return properties;
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/ComparisonSettings.cs
================================================
using System;
using System.Collections.Generic;
namespace ObjectsComparer
{
/// <summary>
/// Configuration for Objects Comparer.
/// </summary>
public class ComparisonSettings
{
/// <summary>
/// If true, all members which are not primitive types, do not have custom comparison rule and
/// do not implement <see cref="IComparable"/> will be compared as separate objects using the same rules as current objects. True by default.
/// </summary>
public bool RecursiveComparison { get; set; }
/// <summary>
/// If true, empty <see cref="System.Collections.IEnumerable"/> and null values will be considered as equal values. False by default.
/// </summary>
public bool EmptyAndNullEnumerablesEqual { get; set; }
/// <summary>
/// If true and member does not exists, objects comparer will consider that this member is equal to default value of opposite member type.
/// Applicable for dynamic types comparison only. False by default.
/// </summary>
public bool UseDefaultIfMemberNotExist { get; set; }
private readonly Dictionary<Tuple<Type, string>, object> _settings = new Dictionary<Tuple<Type, string>, object>();
/// <summary>
/// Initializes a new instance of the <see cref="ComparisonSettings" /> class.
/// </summary>
public ComparisonSettings()
{
RecursiveComparison = true;
EmptyAndNullEnumerablesEqual = false;
UseDefaultIfMemberNotExist = false;
}
/// <summary>
/// Sets value of custom setting. Could be used to pass parameters to custom value comparers.
/// </summary>
/// <typeparam name="T">Setting Type.</typeparam>
/// <param name="value">Setting Value.</param>
/// <param name="key">Setting Key.</param>
public void SetCustomSetting<T>(T value, string key = null)
{
var dictionaryKey = new Tuple<Type, string>(typeof(T), key);
_settings[dictionaryKey] = value;
}
/// <summary>
/// Gets value of custom setting. Could be used in custom value comparers.
/// </summary>
/// <typeparam name="T">Setting Type.</typeparam>
/// <param name="key">Setting Key.</param>
/// <returns>Setting Value.</returns>
public T GetCustomSetting<T>(string key = null)
{
var dictionaryKey = new Tuple<Type, string>(typeof(T), key);
if (_settings.TryGetValue(dictionaryKey, out var value))
{
return (T) value;
}
throw new KeyNotFoundException();
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/AbstractDynamicObjectsComprer.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using ObjectsComparer.Utils;
namespace ObjectsComparer
{
internal abstract class AbstractDynamicObjectsComprer<T>: AbstractComparer, IComparerWithCondition
{
protected AbstractDynamicObjectsComprer(ComparisonSettings settings, BaseComparer parentComparer, IComparersFactory factory) : base(settings, parentComparer, factory)
{
}
public override IEnumerable<Difference> CalculateDifferences(Type type, object obj1, object obj2)
{
var castedObject1 = (T)obj1;
var castedObject2 = (T)obj2;
var propertyKeys1 = GetProperties(castedObject1);
var propertyKeys2 = GetProperties(castedObject2);
var propertyKeys = propertyKeys1.Union(propertyKeys2);
foreach (var propertyKey in propertyKeys)
{
var existsInObject1 = propertyKeys1.Contains(propertyKey);
var existsInObject2 = propertyKeys2.Contains(propertyKey);
object value1 = null;
if (existsInObject1)
{
TryGetMemberValue(castedObject1, propertyKey, out value1);
}
object value2 = null;
if (existsInObject2)
{
TryGetMemberValue(castedObject2, propertyKey, out value2);
}
var propertyType = (value1 ?? value2)?.GetType() ?? typeof(object);
var customComparer = OverridesCollection.GetComparer(propertyType) ??
OverridesCollection.GetComparer(propertyKey);
var valueComparer = customComparer ?? DefaultValueComparer;
if (Settings.UseDefaultIfMemberNotExist)
{
if (!existsInObject1)
{
value1 = propertyType.GetDefaultValue();
}
if (!existsInObject2)
{
value2 = propertyType.GetDefaultValue();
}
}
if (!Settings.UseDefaultIfMemberNotExist)
{
if (!existsInObject1)
{
yield return new Difference(propertyKey, string.Empty, valueComparer.ToString(value2),
DifferenceTypes.MissedMemberInFirstObject);
continue;
}
if (!existsInObject2)
{
yield return new Difference(propertyKey, valueComparer.ToString(value1), string.Empty,
DifferenceTypes.MissedMemberInSecondObject);
continue;
}
}
if (value1 != null && value2 != null && value1.GetType() != value2.GetType())
{
var valueComparer2 = OverridesCollection.GetComparer(value2.GetType()) ??
OverridesCollection.GetComparer(propertyKey) ??
DefaultValueComparer;
yield return new Difference(propertyKey, valueComparer.ToString(value1), valueComparer2.ToString(value2),
DifferenceTypes.TypeMismatch);
continue;
}
//null cannot be casted to ValueType
if (value1 == null && value2 != null && value2.GetType().GetTypeInfo().IsValueType ||
value2 == null && value1 != null && value1.GetType().GetTypeInfo().IsValueType)
{
var valueComparer2 = value2 != null ?
OverridesCollection.GetComparer(value2.GetType()) ?? OverridesCollection.GetComparer(propertyKey) ?? DefaultValueComparer :
DefaultValueComparer;
yield return new Difference(propertyKey, valueComparer.ToString(value1), valueComparer2.ToString(value2),
DifferenceTypes.TypeMismatch);
continue;
}
if (customComparer != null)
{
if (!customComparer.Compare(value1, value2, Settings))
{
yield return new Difference(propertyKey, customComparer.ToString(value1), customComparer.ToString(value2));
}
continue;
}
var comparer = Factory.GetObjectsComparer(propertyType, Settings, this);
foreach (var failure in comparer.CalculateDifferences(propertyType, value1, value2))
{
yield return failure.InsertPath(propertyKey);
}
}
}
public abstract bool IsMatch(Type type, object obj1, object obj2);
public abstract bool IsStopComparison(Type type, object obj1, object obj2);
public abstract bool SkipMember(Type type, MemberInfo member);
protected abstract IList<string> GetProperties(T obj);
protected abstract bool TryGetMemberValue(T obj, string propertyName, out object value);
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/AbstractEnumerablesComparer.cs
================================================
using System;
using System.Collections.Generic;
using System.Reflection;
using ObjectsComparer.Utils;
namespace ObjectsComparer
{
internal abstract class AbstractEnumerablesComparer: AbstractComparer, IComparerWithCondition
{
protected AbstractEnumerablesComparer(ComparisonSettings settings, BaseComparer parentComparer,
IComparersFactory factory)
: base(settings, parentComparer, factory)
{
}
public bool IsStopComparison(Type type, object obj1, object obj2)
{
return Settings.EmptyAndNullEnumerablesEqual && (obj1 == null || obj2 == null);
}
public virtual bool SkipMember(Type type, MemberInfo member)
{
if (type.InheritsFrom(typeof(Array)))
{
if (member.Name == "LongLength")
{
return true;
}
}
if (type.InheritsFrom(typeof(List<>)))
{
if (member.Name == PropertyHelper.GetMemberInfo(() => new List<string>().Capacity).Name)
{
return true;
}
}
return false;
}
public abstract override IEnumerable<Difference> CalculateDifferences(Type type, object obj1, object obj2);
public abstract bool IsMatch(Type type, object obj1, object obj2);
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/CompilerGeneratedObjectComparer.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace ObjectsComparer
{
internal class CompilerGeneratedObjectComparer : AbstractDynamicObjectsComprer<object>
{
public CompilerGeneratedObjectComparer(ComparisonSettings settings, BaseComparer parentComparer, IComparersFactory factory)
: base(settings, parentComparer, factory)
{
}
public override bool IsMatch(Type type, object obj1, object obj2)
{
return (obj1 != null || obj2 != null) &&
(obj1 == null || obj1.GetType().GetTypeInfo().GetCustomAttribute(typeof(CompilerGeneratedAttribute)) != null) &&
(obj2 == null || obj2.GetType().GetTypeInfo().GetCustomAttribute(typeof(CompilerGeneratedAttribute)) != null);
}
public override bool IsStopComparison(Type type, object obj1, object obj2)
{
return true;
}
public override bool SkipMember(Type type, MemberInfo member)
{
return false;
}
protected override IList<string> GetProperties(object obj)
{
return obj?.GetType().GetTypeInfo().GetMembers()
.Where(memberInfo => memberInfo is PropertyInfo)
.Select(memberInfo => memberInfo.Name)
.Distinct()
.ToList() ?? new List<string>();
}
protected override bool TryGetMemberValue(object obj, string propertyName, out object value)
{
value = null;
if (obj == null)
{
return false;
}
var propertyInfo = obj.GetType().GetTypeInfo().GetProperty(propertyName);
if (propertyInfo == null)
{
return false;
}
value = propertyInfo.GetValue(obj);
return true;
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/DynamicObjectComparer.cs
================================================
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Reflection;
using ObjectsComparer.Utils;
namespace ObjectsComparer
{
internal class DynamicObjectComparer : AbstractDynamicObjectsComprer<DynamicObject>
{
private class FakeGetMemberBinder : GetMemberBinder
{
public FakeGetMemberBinder(string name, bool ignoreCase) : base(name, ignoreCase)
{
}
public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
{
throw new NotSupportedException();
}
}
public DynamicObjectComparer(ComparisonSettings settings, BaseComparer parentComparer, IComparersFactory factory)
: base(settings, parentComparer, factory)
{
}
public override bool IsMatch(Type type, object obj1, object obj2)
{
return type.InheritsFrom(typeof(DynamicObject)) ||
(obj1 != null && obj2 != null && type == typeof(object) && obj1.GetType().InheritsFrom(typeof(DynamicObject)) && obj2.GetType().InheritsFrom(typeof(DynamicObject)));
}
public override bool IsStopComparison(Type type, object obj1, object obj2)
{
return obj1 == null || obj2 == null;
}
public override bool SkipMember(Type type, MemberInfo member)
{
return false;
}
protected override IList<string> GetProperties(DynamicObject obj)
{
return obj?.GetDynamicMemberNames().ToList() ?? new List<string>();
}
protected override bool TryGetMemberValue(DynamicObject obj, string propertyName, out object value)
{
if (obj == null)
{
value = null;
return false;
}
var getBinder = new FakeGetMemberBinder(propertyName, false);
return obj.TryGetMember(getBinder, out value);
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/EnumerablesComparer.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using ObjectsComparer.Utils;
namespace ObjectsComparer
{
internal class EnumerablesComparer : AbstractComparer, IComparerWithCondition
{
public EnumerablesComparer(ComparisonSettings settings, BaseComparer parentComparer, IComparersFactory factory)
: base(settings, parentComparer, factory)
{
}
public override IEnumerable<Difference> CalculateDifferences(Type type, object obj1, object obj2)
{
if (!Settings.EmptyAndNullEnumerablesEqual &&
(obj1 == null || obj2 == null) && obj1 != obj2)
{
yield return new Difference("[]", obj1?.ToString() ?? string.Empty, obj2?.ToString() ?? string.Empty);
yield break;
}
obj1 = obj1 ?? Enumerable.Empty<object>();
obj2 = obj2 ?? Enumerable.Empty<object>();
if (!type.InheritsFrom(typeof(IEnumerable)))
{
throw new ArgumentException(nameof(type));
}
if (!obj1.GetType().InheritsFrom(typeof(IEnumerable)))
{
throw new ArgumentException(nameof(obj1));
}
if (!obj2.GetType().InheritsFrom(typeof(IEnumerable)))
{
throw new ArgumentException(nameof(obj2));
}
var array1 = ((IEnumerable)obj1).Cast<object>().ToArray();
var array2 = ((IEnumerable)obj2).Cast<object>().ToArray();
if (array1.Length != array2.Length)
{
yield return new Difference("", array1.Length.ToString(), array2.Length.ToString(),
DifferenceTypes.NumberOfElementsMismatch);
yield break;
}
//ToDo Extract type
for (var i = 0; i < array2.Length; i++)
{
if (array1[i] == null && array2[i] == null)
{
continue;
}
var valueComparer1 = array1[i] != null ? OverridesCollection.GetComparer(array1[i].GetType()) ?? DefaultValueComparer : DefaultValueComparer;
var valueComparer2 = array2[i] != null ? OverridesCollection.GetComparer(array2[i].GetType()) ?? DefaultValueComparer : DefaultValueComparer;
if (array1[i] == null)
{
yield return new Difference($"[{i}]", string.Empty, valueComparer2.ToString(array2[i]));
continue;
}
if (array2[i] == null)
{
yield return new Difference($"[{i}]", valueComparer1.ToString(array1[i]), string.Empty);
continue;
}
if (array1[i].GetType() != array2[i].GetType())
{
yield return new Difference($"[{i}]", valueComparer1.ToString(array1[i]), valueComparer2.ToString(array2[i]), DifferenceTypes.TypeMismatch);
continue;
}
var comparer = Factory.GetObjectsComparer(array1[i].GetType(), Settings, this);
foreach (var failure in comparer.CalculateDifferences(array1[i].GetType(), array1[i], array2[i]))
{
yield return failure.InsertPath($"[{i}]");
}
}
}
public bool IsMatch(Type type, object obj1, object obj2)
{
return type.InheritsFrom(typeof(IEnumerable)) && !type.InheritsFrom(typeof(IEnumerable<>));
}
public bool IsStopComparison(Type type, object obj1, object obj2)
{
return Settings.EmptyAndNullEnumerablesEqual && obj1 == null || obj2 == null;
}
public bool SkipMember(Type type, MemberInfo member)
{
return false;
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/EnumerablesComparer~1.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using ObjectsComparer.Utils;
namespace ObjectsComparer
{
internal class EnumerablesComparer<T> : AbstractComparer
{
private readonly IComparer<T> _comparer;
public EnumerablesComparer(ComparisonSettings settings, BaseComparer parentComparer, IComparersFactory factory)
:base(settings, parentComparer, factory)
{
_comparer = Factory.GetObjectsComparer<T>(Settings, this);
}
public override IEnumerable<Difference> CalculateDifferences(Type type, object obj1, object obj2)
{
if (!type.InheritsFrom(typeof(IEnumerable<>)))
{
throw new ArgumentException("Invalid type");
}
if (!Settings.EmptyAndNullEnumerablesEqual &&
(obj1 == null || obj2 == null) && obj1 != obj2)
{
yield break;
}
obj1 = obj1 ?? Enumerable.Empty<T>();
obj2 = obj2 ?? Enumerable.Empty<T>();
if (!obj1.GetType().InheritsFrom(typeof(IEnumerable<T>)))
{
throw new ArgumentException(nameof(obj1));
}
if (!obj2.GetType().InheritsFrom(typeof(IEnumerable<T>)))
{
throw new ArgumentException(nameof(obj2));
}
var list1 = ((IEnumerable<T>)obj1).ToList();
var list2 = ((IEnumerable<T>)obj2).ToList();
if (list1.Count != list2.Count)
{
if (!type.GetTypeInfo().IsArray)
{
yield return new Difference("", list1.Count.ToString(), list2.Count.ToString(),
DifferenceTypes.NumberOfElementsMismatch);
}
yield break;
}
for (var i = 0; i < list2.Count; i++)
{
foreach (var failure in _comparer.CalculateDifferences(list1[i], list2[i]))
{
yield return failure.InsertPath($"[{i}]");
}
}
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/ExpandoObjectComparer.cs
================================================
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Reflection;
using ObjectsComparer.Utils;
namespace ObjectsComparer
{
internal class ExpandoObjectComparer : AbstractDynamicObjectsComprer<ExpandoObject>
{
public ExpandoObjectComparer(ComparisonSettings settings, BaseComparer parentComparer, IComparersFactory factory)
: base(settings, parentComparer, factory)
{
}
public override bool IsMatch(Type type, object obj1, object obj2)
{
return type.InheritsFrom(typeof(ExpandoObject)) ||
(obj1 != null && obj2 != null && type == typeof(object) && obj1.GetType().InheritsFrom(typeof(ExpandoObject)) && obj2.GetType().InheritsFrom(typeof(ExpandoObject)));
}
public override bool IsStopComparison(Type type, object obj1, object obj2)
{
return obj1 == null || obj2 == null;
}
public override bool SkipMember(Type type, MemberInfo member) => false;
protected override IList<string> GetProperties(ExpandoObject obj)
{
return ((IDictionary<string, object>) obj)?.Keys.ToList() ?? new List<string>();
}
protected override bool TryGetMemberValue(ExpandoObject obj, string propertyName, out object value)
{
if (obj != null)
{
return ((IDictionary<string, object>) obj).TryGetValue(propertyName, out value);
}
value = null;
return false;
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/GenericEnumerablesComparer.cs
================================================
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using ObjectsComparer.Utils;
namespace ObjectsComparer
{
internal class GenericEnumerablesComparer : AbstractEnumerablesComparer
{
public GenericEnumerablesComparer(ComparisonSettings settings, BaseComparer parentComparer,
IComparersFactory factory)
: base(settings, parentComparer, factory)
{
}
public override IEnumerable<Difference> CalculateDifferences(Type type, object obj1, object obj2)
{
if (obj1 == null && obj2 == null)
{
yield break;
}
var typeInfo = (obj1 ?? obj2).GetType().GetTypeInfo();
Type elementType;
if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(IEnumerable<>))
{
elementType = typeInfo.GetElementType();
}
else
{
elementType = typeInfo.GetInterfaces()
.Where(
i =>
i.GetTypeInfo().IsGenericType &&
i.GetTypeInfo().GetGenericTypeDefinition() == typeof(IEnumerable<>))
.Select(i => i.GetTypeInfo().GetGenericArguments()[0])
.First();
}
var enumerablesComparerType = typeof(EnumerablesComparer<>).MakeGenericType(elementType);
var comparer = (IComparer)Activator.CreateInstance(enumerablesComparerType, Settings, this, Factory);
foreach (var difference in comparer.CalculateDifferences(type, obj1, obj2))
{
yield return difference;
}
}
public override bool IsMatch(Type type, object obj1, object obj2)
{
return type.InheritsFrom(typeof(IEnumerable<>));
}
public override bool SkipMember(Type type, MemberInfo member)
{
if (base.SkipMember(type, member))
{
return true;
}
if (type.InheritsFrom(typeof(ICollection<>)) &&
member.Name == PropertyHelper.GetMemberInfo(() => new Collection<string>().Count).Name)
{
return true;
}
if (!type.InheritsFrom(typeof(IDictionary<,>)))
{
return false;
}
return member.Name == PropertyHelper.GetMemberInfo(() => new Dictionary<object, object>().Values).Name ||
member.Name == PropertyHelper.GetMemberInfo(() => new Dictionary<object, object>().Keys).Name;
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/HashSetsComparer.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using ObjectsComparer.Utils;
namespace ObjectsComparer
{
internal class HashSetsComparer : AbstractEnumerablesComparer
{
public HashSetsComparer(ComparisonSettings settings, BaseComparer parentComparer, IComparersFactory factory)
: base(settings, parentComparer, factory)
{
}
public override IEnumerable<Difference> CalculateDifferences(Type type, object obj1, object obj2)
{
if (obj1 == null && obj2 == null)
{
yield break;
}
var typeInfo = (obj1 ?? obj2).GetType().GetTypeInfo();
Type elementType = typeInfo.GetInterfaces()
.Where(
i =>
i.GetTypeInfo().IsGenericType &&
i.GetTypeInfo().GetGenericTypeDefinition() == typeof(ISet<>))
.Select(i => i.GetTypeInfo().GetGenericArguments()[0])
.First();
var enumerablesComparerType = typeof(HashSetsComparer<>).MakeGenericType(elementType);
var comparer = (IComparer)Activator.CreateInstance(enumerablesComparerType, Settings, this, Factory);
foreach (var difference in comparer.CalculateDifferences(type, obj1, obj2))
{
yield return difference;
}
}
public override bool IsMatch(Type type, object obj1, object obj2)
{
return type.InheritsFrom(typeof(HashSet<>));
}
public override bool SkipMember(Type type, MemberInfo member)
{
return base.SkipMember(type, member) ||
member.Name == PropertyHelper.GetMemberInfo(() => new HashSet<string>().Comparer).Name ||
member.Name == PropertyHelper.GetMemberInfo(() => new HashSet<string>().Count).Name;
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/HashSetsComparer~1.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using ObjectsComparer.Utils;
namespace ObjectsComparer
{
internal class HashSetsComparer<T> : AbstractComparer
{
public HashSetsComparer(ComparisonSettings settings, BaseComparer parentComparer, IComparersFactory factory)
:base(settings, parentComparer, factory)
{
}
public override IEnumerable<Difference> CalculateDifferences(Type type, object obj1, object obj2)
{
if (!type.InheritsFrom(typeof(HashSet<>)))
{
throw new ArgumentException("Invalid type");
}
if (!Settings.EmptyAndNullEnumerablesEqual &&
(obj1 == null || obj2 == null) && obj1 != obj2)
{
yield break;
}
obj1 = obj1 ?? new HashSet<T>();
obj2 = obj2 ?? new HashSet<T>();
if (!obj1.GetType().InheritsFrom(typeof(HashSet<T>)))
{
throw new ArgumentException(nameof(obj1));
}
if (!obj2.GetType().InheritsFrom(typeof(HashSet<T>)))
{
throw new ArgumentException(nameof(obj2));
}
var hashSet1 = ((IEnumerable<T>)obj1).ToList();
var hashSet2 = ((IEnumerable<T>)obj2).ToList();
var valueComparer = OverridesCollection.GetComparer(typeof(T)) ?? DefaultValueComparer;
foreach (var element in hashSet1)
{
if (!hashSet2.Contains(element))
{
yield return new Difference("", valueComparer.ToString(element), string.Empty,
DifferenceTypes.MissedElementInSecondObject);
}
}
foreach (var element in hashSet2)
{
if (!hashSet1.Contains(element))
{
yield return new Difference("", string.Empty, valueComparer.ToString(element),
DifferenceTypes.MissedElementInFirstObject);
}
}
}
public bool IsMatch(Type type, object obj1, object obj2)
{
return type.InheritsFrom(typeof(HashSet<>));
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/IComparerWithCondition.cs
================================================
using System;
using System.Reflection;
namespace ObjectsComparer
{
internal interface IComparerWithCondition: IComparer
{
bool IsMatch(Type type, object obj1, object obj2);
bool IsStopComparison(Type type, object obj1, object obj2);
bool SkipMember(Type type, MemberInfo member);
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/MultidimensionalArrayComparer~1.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using ObjectsComparer.Utils;
namespace ObjectsComparer
{
internal class MultidimensionalArrayComparer<T> : AbstractComparer
{
private readonly IComparer<T> _comparer;
public MultidimensionalArrayComparer(ComparisonSettings settings, BaseComparer parentComparer, IComparersFactory factory)
: base(settings, parentComparer, factory)
{
_comparer = Factory.GetObjectsComparer<T>(Settings, this);
}
public override IEnumerable<Difference> CalculateDifferences(Type type, object obj1, object obj2)
{
if (!type.InheritsFrom(typeof(Array)))
{
throw new ArgumentException("Invalid type");
}
if (!Settings.EmptyAndNullEnumerablesEqual &&
(obj1 == null || obj2 == null) && obj1 != obj2)
{
yield break;
}
if (obj1 != null && !obj1.GetType().InheritsFrom(typeof(Array)))
{
throw new ArgumentException(nameof(obj1));
}
if (obj2 != null && !obj2.GetType().InheritsFrom(typeof(Array)))
{
throw new ArgumentException(nameof(obj2));
}
var array1 = (Array)obj1 ?? Array.CreateInstance(typeof(T), new int[type.GetArrayRank()]);
var array2 = (Array)obj2 ?? Array.CreateInstance(typeof(T), new int[type.GetArrayRank()]);
if (array1.Rank != array2.Rank)
{
yield return new Difference("Rank", array1.Rank.ToString(), array2.Rank.ToString());
yield break;
}
var dimensionsFailure = false;
for (var i = 0; i < array1.Rank; i++)
{
var length1 = array1.GetLength(i);
var length2 = array2.GetLength(i);
// ReSharper disable once InvertIf
if (length1 != length2)
{
dimensionsFailure = true;
yield return new Difference($"Dimension{i}", length1.ToString(), length2.ToString());
}
}
if (dimensionsFailure)
{
yield break;
}
for (var i = 0; i < array1.Length; i++)
{
var indecies = IndexToCoordinates(array1, i);
foreach (var failure in _comparer.CalculateDifferences((T)array1.GetValue(indecies), (T)array2.GetValue(indecies)))
{
yield return failure.InsertPath($"[{string.Join(",", indecies)}]");
}
}
}
private static int[] IndexToCoordinates(Array arr, int i)
{
var dims = Enumerable.Range(0, arr.Rank)
.Select(arr.GetLength)
.ToArray();
return dims.Select((d, n) => i / dims.Take(n).Aggregate(1, (i1, i2) => i1 * i2) % d).ToArray();
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/MultidimensionalArraysComparer.cs
================================================
using System;
using System.Collections.Generic;
using System.Reflection;
using ObjectsComparer.Utils;
namespace ObjectsComparer
{
internal class MultidimensionalArraysComparer : AbstractEnumerablesComparer
{
public MultidimensionalArraysComparer(ComparisonSettings settings, BaseComparer parentComparer,
IComparersFactory factory)
: base(settings, parentComparer, factory)
{
}
public override IEnumerable<Difference> CalculateDifferences(Type type, object obj1, object obj2)
{
if (obj1 == null && obj2 == null)
{
yield break;
}
var typeInfo = (obj1 ?? obj2).GetType().GetTypeInfo();
var enumerablesComparerType = typeof(MultidimensionalArrayComparer<>).MakeGenericType(typeInfo.GetElementType());
var comparer = (IComparer)Activator.CreateInstance(enumerablesComparerType, Settings, this, Factory);
foreach (var difference in comparer.CalculateDifferences(type, obj1, obj2))
{
yield return difference;
}
}
public override bool IsMatch(Type type, object obj1, object obj2)
{
return type.GetTypeInfo().IsArray && type.GetTypeInfo().GetArrayRank() > 1;
}
public override bool SkipMember(Type type, MemberInfo member)
{
if (base.SkipMember(type, member))
{
return true;
}
if (!type.IsArray)
{
return false;
}
Array array = new int[0];
return member.Name == PropertyHelper.GetMemberInfo(() => array.Length).Name;
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/TypesComparer.cs
================================================
using System;
using System.Collections.Generic;
using System.Reflection;
using ObjectsComparer.Utils;
namespace ObjectsComparer
{
internal class TypesComparer : AbstractComparer, IComparerWithCondition
{
public TypesComparer(ComparisonSettings settings, BaseComparer parentComparer,
IComparersFactory factory)
: base(settings, parentComparer, factory)
{
}
public override IEnumerable<Difference> CalculateDifferences(Type type, object obj1, object obj2)
{
if (obj1 == null && obj2 == null)
{
yield break;
}
if (obj1?.GetType().InheritsFrom(typeof(Type)) == false)
{
throw new ArgumentException(nameof(obj1));
}
if (obj2?.GetType().InheritsFrom(typeof(Type)) == false)
{
throw new ArgumentException(nameof(obj2));
}
var type1Str = obj1?.ToString();
var type2Str = obj2?.ToString();
if (type1Str != type2Str)
{
yield return new Difference(string.Empty, type1Str, type2Str);
}
}
public bool IsMatch(Type type, object obj1, object obj2)
{
return type.InheritsFrom(typeof(Type));
}
public bool IsStopComparison(Type type, object obj1, object obj2) => true;
public bool SkipMember(Type type, MemberInfo member) => true;
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/Difference.cs
================================================
namespace ObjectsComparer
{
/// <summary>
/// Represents difference in one member between objects.
/// </summary>
public class Difference
{
/// <summary>
/// Path to the member.
/// </summary>
public string MemberPath { get; }
/// <summary>
/// Value in the first object, converted to string.
/// </summary>
public string Value1 { get; }
/// <summary>
/// Value in the second object, converted to string.
/// </summary>
public string Value2 { get; }
/// <summary>
/// Type of the difference.
/// </summary>
public DifferenceTypes DifferenceType { get; }
/// <summary>
/// Initializes a new instance of the <see cref="Difference" /> class.
/// </summary>
/// <param name="memberPath">Member Path.</param>
/// <param name="value1">Value of the first object, converted to string.</param>
/// <param name="value2">Value of the second object, converted to string.</param>
/// <param name="differenceType">Type of the difference.</param>
public Difference(string memberPath, string value1, string value2,
DifferenceTypes differenceType = DifferenceTypes.ValueMismatch)
{
MemberPath = memberPath;
Value1 = value1;
Value2 = value2;
DifferenceType = differenceType;
}
/// <summary>
/// Combines difference with path of the root element.
/// </summary>
/// <param name="path">Root element path.</param>
/// <returns>Difference with combined <see cref="MemberPath"/>.</returns>
public Difference InsertPath(string path)
{
var newPath = string.IsNullOrWhiteSpace(MemberPath) || MemberPath.StartsWith("[")
? path + MemberPath
: path + "." + MemberPath;
return new Difference(
newPath,
Value1,
Value2,
DifferenceType);
}
/// <summary>Returns a string that represents the current object.</summary>
/// <returns>A string that represents the current object.</returns>
public override string ToString()
{
return $"Difference: DifferenceType={DifferenceType}, MemberPath='{MemberPath}', Value1='{Value1}', Value2='{Value2}'.";
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/DifferenceTypes.cs
================================================
using System.Collections;
namespace ObjectsComparer
{
/// <summary>
/// Specifies types of the differences between object members.
/// </summary>
public enum DifferenceTypes
{
/// <summary>
/// Value of the member in first and second objects are not equal.
/// </summary>
ValueMismatch,
/// <summary>
/// Type of the member in first and second objects are not equal.
/// </summary>
TypeMismatch,
/// <summary>
/// Member does not exist in the first object.
/// </summary>
MissedMemberInFirstObject,
/// <summary>
/// Member does not exist in the second object.
/// </summary>
MissedMemberInSecondObject,
/// <summary>
/// First object does not contain element.
/// </summary>
MissedElementInFirstObject,
/// <summary>
/// Second object does not contain element.
/// </summary>
MissedElementInSecondObject,
/// <summary>
/// <see cref="IEnumerable"/>s have different number of elements.
/// </summary>
NumberOfElementsMismatch
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/Exceptions/AmbiguousComparerOverrideResolutionException.cs
================================================
using System;
using System.Reflection;
namespace ObjectsComparer.Exceptions
{
/// <summary>
/// Represents errors that occur when Objects Comparer has more than one comparer override which could be used to compare member.
/// </summary>
public class AmbiguousComparerOverrideResolutionException: Exception
{
/// <summary>
/// Name of the Member that was a cause of exception
/// </summary>
public string MemberName { get; }
/// <summary>
/// MemberInfo of the Member that was a cause of exception
/// </summary>
public MemberInfo MemberInfo { get; }
/// <summary>
/// Type that was a cause of exception
/// </summary>
public Type Type { get; }
internal AmbiguousComparerOverrideResolutionException(MemberInfo memberInfo)
: base($"Unable to resolve comparer for member {memberInfo.MemberType}. More than one value comparer meet criteria for this member.")
{
MemberInfo = memberInfo;
MemberName = memberInfo.Name;
}
internal AmbiguousComparerOverrideResolutionException(string memberName)
: base($"Unable to resolve comparer for member {memberName}. More than one value comparer meet criteria for this member.")
{
MemberName = memberName;
}
internal AmbiguousComparerOverrideResolutionException(Type type)
: base($"Unable to resolve comparer for type {type.GetTypeInfo().FullName}. More than one value comparer meet criteria for this type.")
{
Type = type;
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/Exceptions/ValueComparerExistsException.cs
================================================
using System;
using System.Reflection;
namespace ObjectsComparer.Exceptions
{
/// <summary>
/// Represents errors that occur when comparer for Member has already been added.
/// </summary>
public class ValueComparerExistsException: Exception
{
/// <summary>
/// MemberInfo of the Member that was a cause of exception
/// </summary>
public MemberInfo MemberInfo { get; }
internal ValueComparerExistsException(MemberInfo memberInfo)
: base($"Comparer override for member {memberInfo.MemberType} has already been added.")
{
MemberInfo = memberInfo;
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/IBaseComparer.cs
================================================
using System;
using System.Linq.Expressions;
using System.Reflection;
namespace ObjectsComparer
{
/// <summary>
/// Defines properties and methods to configure comparer.
/// </summary>
public interface IBaseComparer
{
/// <summary>
/// Default <see cref="IValueComparer"/>
/// </summary>
IValueComparer DefaultValueComparer { get; }
/// <summary>
/// Comparison Settings.
/// </summary>
ComparisonSettings Settings { get; }
/// <summary>
/// Sets <see cref="DefaultValueComparer"/>.
/// </summary>
/// <param name="valueComparer">Value Comparer.</param>
void SetDefaultComparer(IValueComparer valueComparer);
/// <summary>
/// Adds Comparer Override by Member.
/// </summary>
/// <typeparam name="TProp">Type of the member.</typeparam>
/// <param name="memberLambda">Lambda to get member.</param>
/// <param name="valueComparer">Value Comparer.</param>
void AddComparerOverride<TProp>(Expression<Func<TProp>> memberLambda, IValueComparer valueComparer);
/// <summary>
/// Adds Comparer Override by Member.
/// </summary>
/// <param name="memberInfo">Member Info.</param>
/// <param name="valueComparer">Value Comparer.</param>
void AddComparerOverride(MemberInfo memberInfo, IValueComparer valueComparer);
/// <summary>
/// Adds Comparer Override by Type.
/// </summary>
/// <param name="type">Type.</param>
/// <param name="valueComparer">Value Comparer.</param>
/// <param name="filter">Value Comparer will be used only if filter(memberInfo) == true. Null by default.</param>
void AddComparerOverride(Type type, IValueComparer valueComparer, Func<MemberInfo, bool> filter = null);
/// <summary>
/// Adds Comparer Override by Type.
/// </summary>
/// <typeparam name="TType">Type.</typeparam>
/// <param name="valueComparer">Value Comparer.</param>
/// <param name="filter">Value Comparer will be used only if filter(memberInfo) == true. Null by default.</param>
void AddComparerOverride<TType>(IValueComparer valueComparer, Func<MemberInfo, bool> filter = null);
/// <summary>
/// Adds Comparer Override by Member.
/// </summary>
/// <typeparam name="TProp">Type of the member.</typeparam>
/// <param name="memberLambda">Lambda to get member.</param>
/// <param name="compareFunction">Function to compare objects.</param>
/// <param name="toStringFunction">Function to convert objects to string.</param>
void AddComparerOverride<TProp>(
Expression<Func<TProp>> memberLambda,
Func<TProp, TProp, ComparisonSettings, bool> compareFunction,
Func<TProp, string> toStringFunction);
/// <summary>
/// Adds Comparer Override by Member.
/// </summary>
/// <typeparam name="TProp">Type of the member.</typeparam>
/// <param name="memberLambda">Lambda to get member.</param>
/// <param name="compareFunction">Function to compare objects.</param>
void AddComparerOverride<TProp>(
Expression<Func<TProp>> memberLambda,
Func<TProp, TProp, ComparisonSettings, bool> compareFunction);
/// <summary>
/// Adds Comparer Override by Member name.
/// </summary>
/// <param name="memberName">Member Name.</param>
/// <param name="valueComparer">Value Comparer.</param>
/// <param name="filter">Value Comparer will be used only if filter(memberInfo) == true. Null by default.</param>
void AddComparerOverride(string memberName, IValueComparer valueComparer, Func<MemberInfo, bool> filter = null);
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/IComparer.cs
================================================
using System;
using System.Collections.Generic;
namespace ObjectsComparer
{
/// <summary>
/// Defines methods to compare complex objects.
/// </summary>
public interface IComparer : IBaseComparer
{
/// <summary>
/// Compares objects.
/// </summary>
/// <param name="type">Type.</param>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <param name="differences">List of differences.</param>
/// <returns>True if objects are equal, otherwise false.</returns>
bool Compare(Type type, object obj1, object obj2, out IEnumerable<Difference> differences);
/// <summary>
/// Compares objects.
/// </summary>
/// <typeparam name="T">Type.</typeparam>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <param name="differences">List of differences.</param>
/// <returns>True if objects are equal, otherwise false.</returns>
bool Compare<T>(T obj1, T obj2, out IEnumerable<Difference> differences);
/// <summary>
/// Compares objects.
/// </summary>
/// <param name="type">Type.</param>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <returns>True if objects are equal, otherwise false.</returns>
bool Compare(Type type, object obj1, object obj2);
/// <summary>
/// Compares objects.
/// </summary>
/// <typeparam name="T">Type.</typeparam>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <returns>True if objects are equal, otherwise false.</returns>
bool Compare<T>(T obj1, T obj2);
/// <summary>
/// Calculates list of differences between objects.
/// </summary>
/// <param name="type">Type.</param>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <returns>List of differences between objects.</returns>
IEnumerable<Difference> CalculateDifferences(Type type, object obj1, object obj2);
/// <summary>
/// Calculates list of differences between objects.
/// </summary>
/// <typeparam name="T">Type.</typeparam>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <returns>List of differences between objects.</returns>
IEnumerable<Difference> CalculateDifferences<T>(T obj1, T obj2);
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/IComparersFactory.cs
================================================
using System;
namespace ObjectsComparer
{
/// <summary>
/// Defines methods to create type specific comparers.
/// </summary>
public interface IComparersFactory
{
/// <summary>
/// Creates type specific comparer.
/// </summary>
/// <typeparam name="T">Type.</typeparam>
/// <param name="settings">Comparison Settings. Null by default.</param>
/// <param name="parentComparer">Parent comparer. Null by default.</param>
/// <returns>Instance of <see cref="IComparer{T}"/>.</returns>
IComparer<T> GetObjectsComparer<T>(ComparisonSettings settings = null, BaseComparer parentComparer = null);
/// <summary>
/// Creates type specific comparer.
/// </summary>
/// <param name="type">Type.</param>
/// <param name="settings">Comparison Settings. Null by default.</param>
/// <param name="parentComparer">Parent comparer. Null by default.</param>
/// <returns>Instance of <see cref="IComparer"/>.</returns>
IComparer GetObjectsComparer(Type type, ComparisonSettings settings = null, BaseComparer parentComparer = null);
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/IComparer~1.cs
================================================
using System.Collections.Generic;
namespace ObjectsComparer
{
/// <summary>
/// Defines methods to compare complex objects of particular type.
/// </summary>
public interface IComparer<in T>: IBaseComparer
{
/// <summary>
/// Compares objects.
/// </summary>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <param name="differences">List of differences.</param>
/// <returns>True if objects are equal, otherwise false.</returns>
bool Compare(T obj1, T obj2, out IEnumerable<Difference> differences);
/// <summary>
/// Compares objects.
/// </summary>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <returns>True if objects are equal, otherwise false.</returns>
bool Compare(T obj1, T obj2);
/// <summary>
/// Calculates list of differences between objects.
/// </summary>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <returns>List of differences between objects.</returns>
IEnumerable<Difference> CalculateDifferences(T obj1, T obj2);
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/LICENSE
================================================
MIT License
Copyright (c) 2019 Valerii Tereshchenko
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: ObjectsComparer/ObjectsComparer/ObjectsComparer.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.1;netstandard2.0;netstandard1.6;net45</TargetFrameworks>
<Version>1.4.1</Version>
<Authors>Valerii Tereshchenko</Authors>
<Company />
<Product>Objects Data Comparer</Product>
<Description>Framework provides mechanism to compare classes, allows override comparison rules for specific properties and types.</Description>
<Copyright>Copyright © Valerii Tereshchenko 2019</Copyright>
<PackageLicenseUrl></PackageLicenseUrl>
<PackageProjectUrl>https://github.com/ValeraT1982/ObjectsComparer</PackageProjectUrl>
<PackageIconUrl>https://github.com/ValeraT1982/ObjectsComparer/blob/master/ObjectsDataComparer.png?raw=true</PackageIconUrl>
<RepositoryUrl>https://github.com/ValeraT1982/ObjectsComparer</RepositoryUrl>
<PackageTags>C#, compare, class, reflection, object, comparison</PackageTags>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Dynamic.Runtime" Version="4.3.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
<None Include="LICENSE" Pack="true" PackagePath="" />
</ItemGroup>
</Project>
================================================
FILE: ObjectsComparer/ObjectsComparer/ObjectsComparer.csproj.DotSettings
================================================
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=customcomparers/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=valuecomparers/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
================================================
FILE: ObjectsComparer/ObjectsComparer/Properties/AssemblyInfo.cs
================================================
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("ObjectsComparer.Tests")]
================================================
FILE: ObjectsComparer/ObjectsComparer/Utils/MemberInfoExtensions.cs
================================================
using System;
using System.Linq.Expressions;
using System.Reflection;
namespace ObjectsComparer.Utils
{
internal static class MemberInfoExtensions
{
public static Type GetMemberType(this MemberInfo memberInfo)
{
var propertyInfo = memberInfo as PropertyInfo;
if (propertyInfo != null)
{
return propertyInfo.PropertyType;
}
var fieldInfo = memberInfo as FieldInfo;
if (fieldInfo != null)
{
return fieldInfo.FieldType;
}
throw new Exception("Unsupported Type");
}
public static object GetMemberValue(this MemberInfo memberInfo, object obj)
{
var propertyInfo = memberInfo as PropertyInfo;
if (propertyInfo != null)
{
try
{
return propertyInfo.GetValue(obj);
}
catch
{
return $"Unable to get value of property {memberInfo.Name} of type {memberInfo.DeclaringType}";
}
}
var fieldInfo = memberInfo as FieldInfo;
if (fieldInfo != null)
{
return fieldInfo.GetValue(obj);
}
throw new Exception("Unsupported Type");
}
public static string GetMethodName<T>(Expression<Action<T>> expression)
{
return ((MethodCallExpression)expression.Body).Method.Name;
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/Utils/PropertyHelper.cs
================================================
using System;
using System.Linq.Expressions;
using System.Reflection;
namespace ObjectsComparer.Utils
{
internal class PropertyHelper
{
public static MemberInfo GetMemberInfo<T>(Expression<Func<T>> memberLambda)
{
MemberExpression exp;
//this line is necessary, because sometimes the expression comes in as Convert(originalexpression)
switch (memberLambda.Body)
{
case UnaryExpression body:
var unExp = body;
if (unExp.Operand is MemberExpression operand)
{
exp = operand;
}
else
{
throw new ArgumentException();
}
break;
case MemberExpression _:
exp = (MemberExpression)memberLambda.Body;
break;
default:
throw new ArgumentException();
}
return exp.Member;
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/Utils/TypeExtensions.cs
================================================
using System;
using System.Linq;
using System.Reflection;
namespace ObjectsComparer.Utils
{
internal static class TypeExtensions
{
public static bool InheritsFrom(this Type t1, Type t2)
{
if (null == t1 || null == t2)
{
return false;
}
if (t1 == t2)
{
return true;
}
if (t1.GetTypeInfo().IsGenericType && t1.GetTypeInfo().GetGenericTypeDefinition() == t2)
{
return true;
}
if (t1.GetTypeInfo().GetInterfaces().Any(i => i.GetTypeInfo().IsGenericType && i.GetGenericTypeDefinition() == t2 || i == t2))
{
return true;
}
return t1.GetTypeInfo().BaseType != null &&
InheritsFrom(t1.GetTypeInfo().BaseType, t2);
}
public static bool IsComparable(this Type type)
{
return type.GetTypeInfo().IsPrimitive ||
type.GetTypeInfo().IsEnum ||
type.InheritsFrom(typeof(IComparable)) ||
type.InheritsFrom(typeof(IComparable<>));
}
public static object GetDefaultValue(this Type t)
{
if (t.GetTypeInfo().IsValueType && Nullable.GetUnderlyingType(t) == null)
{
return Activator.CreateInstance(t);
}
return null;
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/AbstractValueComparer.cs
================================================
namespace ObjectsComparer
{
/// <summary>
/// Implementation of <see cref="IValueComparer"/> which provides simplest implementation of <see cref="ToString(object)"/> method.
/// </summary>
public abstract class AbstractValueComparer: IValueComparer
{
public abstract bool Compare(object obj1, object obj2, ComparisonSettings settings);
public virtual string ToString(object value)
{
return value?.ToString();
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/AbstractValueComparer~1.cs
================================================
namespace ObjectsComparer
{
/// <summary>
/// Implementation of <see cref="IValueComparer{T}"/> which provides simplest implementation of <see cref="ToString(T)"/> method and
/// <see cref="Compare(object, object, ComparisonSettings)"/> method to call <see cref="Compare(T, T, ComparisonSettings)"/>.
/// </summary>
/// <typeparam name="T">Type of the objects.</typeparam>
public abstract class AbstractValueComparer<T>: AbstractValueComparer, IValueComparer<T>
{
/// <summary>
/// Comparers <paramref name="obj1"/> and <paramref name="obj2"/>.
/// </summary>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <param name="settings">Instance of <see cref="ComparisonSettings"/> class.</param>
/// <returns>true if the objects are considered equal; otherwise, false.</returns>
public abstract bool Compare(T obj1, T obj2, ComparisonSettings settings);
/// <summary>
/// Converts values of comparing objects to <see cref="string"/>.
/// </summary>
/// <param name="value">Object to convert.</param>
/// <returns>A string that represents <see cref="value"/>.</returns>
public virtual string ToString(T value)
{
return base.ToString(value);
}
/// <summary>
/// Comparers <paramref name="obj1"/> and <paramref name="obj2"/>.
/// </summary>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <param name="settings">Instance of <see cref="ComparisonSettings"/> class.</param>
/// <returns>true if the objects are considered equal; otherwise, false.</returns>
public override bool Compare(object obj1, object obj2, ComparisonSettings settings)
{
return Compare((T) obj1, (T) obj2, settings);
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/DefaultValueComparer.cs
================================================
namespace ObjectsComparer
{
/// <summary>
/// Default implementation of <see cref="IValueComparer"/>
/// </summary>
public class DefaultValueComparer: IValueComparer
{
private static volatile IValueComparer _instance;
/// <summary>
/// Static <see cref="DefaultValueComparer"/> instance.
/// </summary>
public static IValueComparer Instance
{
get
{
if (_instance != null)
{
return _instance;
}
lock (SyncRoot)
{
if (_instance == null)
{
_instance = new DefaultValueComparer();
}
}
return _instance;
}
}
private static readonly object SyncRoot = new object();
/// <summary>
/// Comparers <paramref name="obj1"/> and <paramref name="obj2"/>.
/// </summary>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <param name="settings">Instance of <see cref="ComparisonSettings"/> class.</param>
/// <returns>true if the objects are considered equal; otherwise, false.</returns>
public bool Compare(object obj1, object obj2, ComparisonSettings settings)
{
if (obj1 == null || obj2 == null)
{
return obj1 == obj2;
}
return obj1.Equals(obj2);
}
/// <summary>
/// Converts values of comparing objects to <see cref="string"/>.
/// </summary>
/// <param name="value">Object to convert.</param>
/// <returns>A string that represents <see cref="value"/>.</returns>
public string ToString(object value)
{
return value?.ToString() ?? string.Empty;
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/DefaultValueValueComparer.cs
================================================
namespace ObjectsComparer
{
/// <summary>
/// Allows to consider provided value and default value of type <see cref="T"/> as equal values.
/// </summary>
/// <typeparam name="T">Type of the objects.</typeparam>
public class DefaultValueValueComparer<T> : IValueComparer
{
private readonly T _defaultValue;
private readonly T _typeDefaultValue;
private readonly IValueComparer _valueComparer;
/// <summary>
/// Initializes a new instance of the <see cref="DefaultValueValueComparer{T}" /> class.
/// </summary>
/// <param name="defaultValue">Default value.</param>
/// <param name="valueComparer">Instance of <see cref="IValueComparer"/> which is used when values are not defaults.</param>
public DefaultValueValueComparer(T defaultValue, IValueComparer valueComparer)
{
_defaultValue = defaultValue;
_valueComparer = valueComparer;
_typeDefaultValue = default(T);
}
/// <summary>
/// Comparers <paramref name="obj1"/> and <paramref name="obj2"/>.
/// </summary>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <param name="settings">Instance of <see cref="ComparisonSettings"/> class.</param>
/// <returns>true if the objects are considered equal; otherwise, false.</returns>
public bool Compare(object obj1, object obj2, ComparisonSettings settings)
{
var isObj1Default = obj1?.Equals(_defaultValue) != false || obj1.Equals(_typeDefaultValue);
var isObj2Default = obj2?.Equals(_defaultValue) != false || obj2.Equals(_typeDefaultValue);
return isObj1Default && isObj2Default || _valueComparer.Compare(obj1, obj2, settings);
}
/// <summary>
/// Converts values of comparing objects to <see cref="string"/>.
/// </summary>
/// <param name="value">Object to convert.</param>
/// <returns>A string that represents <see cref="value"/>.</returns>
public string ToString(object value)
{
return value?.Equals(_typeDefaultValue) != false ? _valueComparer.ToString(_defaultValue) : _valueComparer.ToString(value);
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/DoNotCompareValueComparer.cs
================================================
namespace ObjectsComparer
{
/// <summary>
/// Allows to ignore comparison. Considers all values as equal.
/// </summary>
public class DoNotCompareValueComparer : IValueComparer
{
private static volatile IValueComparer _instance;
/// <summary>
/// Static <see cref="DoNotCompareValueComparer"/> instance.
/// </summary>
public static IValueComparer Instance
{
get
{
if (_instance != null)
{
return _instance;
}
lock (SyncRoot)
{
if (_instance == null)
{
_instance = new DoNotCompareValueComparer();
}
}
return _instance;
}
}
private static readonly object SyncRoot = new object();
private DoNotCompareValueComparer() { }
/// <summary>
/// Comparers <paramref name="obj1"/> and <paramref name="obj2"/>.
/// </summary>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <param name="settings">Instance of <see cref="ComparisonSettings"/> class.</param>
/// <returns>true if the objects are considered equal; otherwise, false.</returns>
public bool Compare(object obj1, object obj2, ComparisonSettings settings)
{
return true;
}
/// <summary>
/// Converts values of comparing objects to <see cref="string"/>.
/// </summary>
/// <param name="value">Object to convert.</param>
/// <returns>A string that represents <see cref="value"/>.</returns>
public string ToString(object value)
{
return string.Empty;
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/DynamicValueComparer.cs
================================================
using System;
using System.Reflection;
namespace ObjectsComparer
{
/// <summary>
/// Allows to provide comparison rule as a function.
/// </summary>
/// <typeparam name="T">Type of the objects.</typeparam>
public class DynamicValueComparer<T>: IValueComparer
{
private readonly Func<T, T, ComparisonSettings, bool> _compareFunction;
private readonly Func<T, string> _toStringFunction;
/// <summary>
/// Initializes a new instance of the <see cref="DynamicValueComparer{T}" /> class.
/// </summary>
/// <param name="compareFunction">Function to compare objects of type <see cref="T"/>.</param>
public DynamicValueComparer(Func<T, T, ComparisonSettings, bool> compareFunction): this(compareFunction, obj => obj?.ToString() ?? string.Empty)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="DynamicValueComparer{T}" /> class.
/// </summary>
/// <param name="compareFunction">Function to compare objects of type <see cref="T"/>.</param>
/// <param name="toStringFunction">Function to convert objects of type <see cref="T"/> to <see cref="string"/>.</param>
public DynamicValueComparer(Func<T, T, ComparisonSettings, bool> compareFunction, Func<T, string> toStringFunction)
{
_compareFunction = compareFunction ?? throw new ArgumentNullException(nameof(compareFunction));
_toStringFunction = toStringFunction ?? throw new ArgumentNullException(nameof(toStringFunction));
}
/// <summary>
/// Comparers <paramref name="obj1"/> and <paramref name="obj2"/>.
/// </summary>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <param name="settings">Instance of <see cref="ComparisonSettings"/> class.</param>
/// <returns>true if the objects are considered equal; otherwise, false.</returns>
public bool Compare(object obj1, object obj2, ComparisonSettings settings)
{
IsArgumentException(obj1, nameof(obj1));
IsArgumentException(obj2, nameof(obj2));
return _compareFunction((T)obj1, (T)obj2, settings);
}
/// <summary>
/// Converts values of comparing objects to <see cref="string"/>.
/// </summary>
/// <param name="value">Object to convert.</param>
/// <returns>A string that represents <see cref="value"/>.</returns>
public string ToString(object value)
{
IsArgumentException(value, nameof(value));
return _toStringFunction((T)value);
}
// ReSharper disable once UnusedParameter.Local
private void IsArgumentException(object obj, string argumentName)
{
var t = typeof(T).GetTypeInfo();
if (!(obj is T) && !((t.IsClass || Nullable.GetUnderlyingType(typeof(T)) != null) && obj == null))
{
throw new ArgumentException(argumentName);
}
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/IValueComparer.cs
================================================
namespace ObjectsComparer
{
/// <summary>
/// Defines a generalized comparison method to compare 2 objects.
/// </summary>
public interface IValueComparer
{
/// <summary>
/// Comparers <paramref name="obj1"/> and <paramref name="obj2"/>.
/// </summary>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <param name="settings">Instance of <see cref="ComparisonSettings"/> class.</param>
/// <returns>true if the objects are considered equal; otherwise, false.</returns>
bool Compare(object obj1, object obj2, ComparisonSettings settings);
/// <summary>
/// Converts values of comparing objects to <see cref="string"/>.
/// </summary>
/// <param name="value">Object to convert.</param>
/// <returns>A string that represents <see cref="value"/>.</returns>
string ToString(object value);
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/IValueComparer~1.cs
================================================
namespace ObjectsComparer
{
/// <summary>
/// Defines a generalized type-specific comparison method to compare 2 objects.
/// </summary>
/// <typeparam name="T">Type of the objects.</typeparam>
public interface IValueComparer<in T>: IValueComparer
{
/// <summary>
/// Comparers <paramref name="obj1"/> and <paramref name="obj2"/>.
/// </summary>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <param name="settings">Instance of <see cref="ComparisonSettings"/> class.</param>
/// <returns>true if the objects are considered equal; otherwise, false.</returns>
bool Compare(T obj1, T obj2, ComparisonSettings settings);
/// <summary>
/// Converts values of comparing objects to <see cref="string"/>.
/// </summary>
/// <param name="value">Object to convert.</param>
/// <returns>A string that represents <see cref="value"/>.</returns>
string ToString(T value);
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/IgnoreCaseStringsValueComparer.cs
================================================
using System;
namespace ObjectsComparer
{
/// <summary>
/// Allows to compare string ignoring case.
/// </summary>
public class IgnoreCaseStringsValueComparer : AbstractValueComparer<string>
{
private static volatile IValueComparer _instance;
/// <summary>
/// Static <see cref="IgnoreCaseStringsValueComparer"/> instance.
/// </summary>
public static IValueComparer Instance
{
get
{
if (_instance != null)
{
return _instance;
}
lock (SyncRoot)
{
if (_instance == null)
{
_instance = new IgnoreCaseStringsValueComparer();
}
}
return _instance;
}
}
private static readonly object SyncRoot = new object();
/// <summary>
/// Comparers <paramref name="obj1"/> and <paramref name="obj2"/>.
/// </summary>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <param name="settings">Instance of <see cref="ComparisonSettings"/> class.</param>
/// <returns>true if the objects are considered equal; otherwise, false.</returns>
public override bool Compare(string obj1, string obj2, ComparisonSettings settings)
{
return string.Compare(obj1, obj2, StringComparison.CurrentCultureIgnoreCase) == 0;
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/NulableStringsValueComparer.cs
================================================
namespace ObjectsComparer
{
/// <summary>
/// Allows to compare strings considering that null and empty string are equal.
/// </summary>
public class NulableStringsValueComparer: AbstractValueComparer<string>
{
private static volatile IValueComparer<string> _instance;
/// <summary>
/// Static <see cref="NulableStringsValueComparer"/> instance.
/// </summary>
public static IValueComparer Instance
{
get
{
if (_instance != null)
{
return _instance;
}
lock (SyncRoot)
{
if (_instance == null)
{
_instance = new NulableStringsValueComparer();
}
}
return _instance;
}
}
private static readonly object SyncRoot = new object();
/// <summary>
/// Comparers <paramref name="obj1"/> and <paramref name="obj2"/>.
/// </summary>
/// <param name="obj1">Object 1.</param>
/// <param name="obj2">Object 2.</param>
/// <param name="settings">Instance of <see cref="ComparisonSettings"/> class.</param>
/// <returns>true if the objects are considered equal; otherwise, false.</returns>
public override bool Compare(string obj1, string obj2, ComparisonSettings settings)
{
if (obj1 == null)
{
obj1 = string.Empty;
}
if (obj2 == null)
{
obj2 = string.Empty;
}
return obj1.Equals(obj2);
}
public override string ToString(string value)
{
return value ?? string.Empty;
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/ToStringComparer.cs
================================================
namespace ObjectsComparer
{
public class ToStringComparer<T> : DynamicValueComparer<T>
{
public ToStringComparer() :
base((uri1, uri2, settings) => uri1?.ToString() == uri2?.ToString())
{
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/UriComparer.cs
================================================
using System;
namespace ObjectsComparer
{
public class UriComparer: DynamicValueComparer<Uri>
{
private static volatile UriComparer _instance;
/// <summary>
/// Static <see cref="UriComparer"/> instance.
/// </summary>
public static IValueComparer Instance
{
get
{
if (_instance != null)
{
return _instance;
}
lock (SyncRoot)
{
if (_instance == null)
{
_instance = new UriComparer();
}
}
return _instance;
}
}
private static readonly object SyncRoot = new object();
public UriComparer() :
base((uri1, uri2, settings) => uri1.OriginalString == uri2.OriginalString, (uri) => uri.OriginalString)
{
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Examples/BasicExamples/BasicExampleTests.cs
================================================
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.Globalization;
using System.Linq;
using System.Text;
using NUnit.Framework;
using static ObjectsComparer.Examples.OutputHelper;
// ReSharper disable PossibleMultipleEnumeration
namespace ObjectsComparer.Examples.BasicExamples
{
[TestFixture]
public class BasicExampleTests
{
#region Basic
[Test]
public void BasicEquality()
{
var a1 = new ClassA { StringProperty = "String", IntProperty = 1 };
var a2 = new ClassA { StringProperty = "String", IntProperty = 1 };
var comparer = new Comparer<ClassA>();
var isEqual = comparer.Compare(a1, a2, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsTrue(isEqual);
}
[Test]
public void BasicInequality()
{
var a1 = new ClassA { StringProperty = "String", IntProperty = 1 };
var a2 = new ClassA { StringProperty = "String", IntProperty = 2 };
var comparer = new Comparer<ClassA>();
var isEqual = comparer.Compare(a1, a2, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsFalse(isEqual);
Assert.AreEqual(1, differences.Count());
Assert.IsTrue(differences.Any(d => d.MemberPath == "IntProperty" && d.Value1 == "1" && d.Value2 == "2"));
}
[Test]
public void BasicInequalityWhenSubclass()
{
var a1 = new ClassA { SubClass = new SubClassA { BoolProperty = true } };
var a2 = new ClassA { SubClass = new SubClassA { BoolProperty = false } };
var comparer = new Comparer<ClassA>();
var isEqual = comparer.Compare(a1, a2, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsFalse(isEqual);
Assert.AreEqual(1, differences.Count());
Assert.IsTrue(differences.Any(d => d.MemberPath == "SubClass.BoolProperty" && d.Value1 == "True" && d.Value2 == "False"));
}
#endregion
#region Generic Enumerables
[Test]
public void GenericEnumerablesEquality()
{
var a1 = new[] { 1, 2, 3 };
var a2 = new[] { 1, 2, 3 };
var comparer = new Comparer<int[]>();
var isEqual = comparer.Compare(a1, a2, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsTrue(isEqual);
}
[Test]
public void GenericEnumerablesInequalityWhenDifferentLength()
{
var a1 = new[] { 1, 2 };
var a2 = new[] { 1, 2, 3 };
var comparer = new Comparer<int[]>();
var isEqual = comparer.Compare(a1, a2, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsFalse(isEqual);
Assert.AreEqual(1, differences.Count());
Assert.IsTrue(differences.Any(d => d.MemberPath == "Length" && d.Value1 == "2" && d.Value2 == "3"));
}
[Test]
public void GenericEnumerablesInequalityWhenDifferentValue()
{
var a1 = new[] { 1, 2, 3 };
var a2 = new[] { 1, 4, 3 };
var comparer = new Comparer<int[]>();
var isEqual = comparer.Compare(a1, a2, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsFalse(isEqual);
Assert.AreEqual(1, differences.Count());
Assert.IsTrue(differences.Any(d => d.MemberPath == "[1]" && d.Value1 == "2" && d.Value2 == "4"));
}
#endregion
#region Hash Sets
[Test]
public void HashSetsEquality()
{
var a1 = new HashSet<int>{ 1, 2, 3 };
var a2 = new HashSet<int> { 1, 2, 3 };
var comparer = new Comparer<HashSet<int>>();
var isEqual = comparer.Compare(a1, a2, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsTrue(isEqual);
}
[Test]
public void HashSetsInequality()
{
var a1 = new HashSet<int> { 1, 2, 3 };
var a2 = new HashSet<int> { 2, 1, 4 };
var comparer = new Comparer<HashSet<int>>();
var isEqual = comparer.Compare(a1, a2, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsFalse(isEqual);
Assert.AreEqual(2, differences.Count());
Assert.IsTrue(differences.Any(d => d.DifferenceType == DifferenceTypes.MissedElementInFirstObject && d.Value2 == "4"));
Assert.IsTrue(differences.Any(d => d.DifferenceType == DifferenceTypes.MissedElementInSecondObject && d.Value1 == "3"));
}
#endregion
#region String Builder
[Test]
public void StringBuilderEquality()
{
var a1 = new StringBuilder("abc");
var a2 = new StringBuilder("abc");
var comparer = new Comparer<StringBuilder>();
var isEqual = comparer.Compare(a1, a2, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsTrue(isEqual);
}
[Test]
public void StringBuilderInequality()
{
var a1 = new StringBuilder("abc");
var a2 = new StringBuilder("abd");
var comparer = new Comparer<StringBuilder>();
var isEqual = comparer.Compare(a1, a2, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsFalse(isEqual);
Assert.AreEqual(1, differences.Count());
Assert.IsTrue(differences.Any(d => d.DifferenceType == DifferenceTypes.ValueMismatch && d.Value1 == "abc" && d.Value2 == "abd"));
}
#endregion
#region Non-Generic Enumerables
[Test]
public void NonGenericWhenDifferentTypes()
{
var a1 = new ArrayList { "Str1", "Str2" };
var a2 = new ArrayList { "Str1", 5 };
var comparer = new Comparer<ArrayList>();
var isEqual = comparer.Compare(a1, a2, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsFalse(isEqual);
Assert.AreEqual("[1]", differences.First().MemberPath);
Assert.AreEqual(DifferenceTypes.TypeMismatch, differences.First().DifferenceType);
Assert.AreEqual("Str2", differences.First().Value1);
Assert.AreEqual("5", differences.First().Value2);
}
#endregion
#region Multidimensional Arrays
[Test]
public void MultidimensionalArraysInequality()
{
var a1 = new[] { new[] { 1, 2 } };
var a2 = new[] { new[] { 1, 3 } };
var comparer = new Comparer<int[][]>();
var isEqual = comparer.Compare(a1, a2, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsFalse(isEqual);
Assert.AreEqual(1, differences.Count());
Assert.AreEqual("[0][1]", differences.First().MemberPath);
Assert.AreEqual("2", differences.First().Value1);
Assert.AreEqual("3", differences.First().Value2);
}
[Test]
public void MultidimensionalArraysSizeInequality1()
{
var a1 = new[] { new[] { 1, 2 } };
var a2 = new[] { new[] { 2, 2 }, new[] { 3, 5 } };
var comparer = new Comparer<int[][]>();
var isEqual = comparer.Compare(a1, a2, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsFalse(isEqual);
CollectionAssert.IsNotEmpty(differences);
Assert.AreEqual(1, differences.Count());
Assert.AreEqual("Length", differences.First().MemberPath);
Assert.AreEqual("1", differences.First().Value1);
Assert.AreEqual("2", differences.First().Value2);
}
[Test]
public void MultidimensionalArraysSizeInequality2()
{
var a1 = new[] { new[] { 1, 2 }, new[] { 3, 5 } };
var a2 = new[] { new[] { 1, 2 }, new[] { 3, 5, 6 } };
var comparer = new Comparer<int[][]>();
var isEqual = comparer.Compare(a1, a2, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsFalse(isEqual);
CollectionAssert.IsNotEmpty(differences);
Assert.AreEqual(1, differences.Count());
Assert.AreEqual("[1].Length", differences.First().MemberPath);
Assert.AreEqual("2", differences.First().Value1);
Assert.AreEqual("3", differences.First().Value2);
}
[Test]
public void IntIntInequality()
{
var a1 = new[,] { { 1, 2 } };
var a2 = new[,] { { 1, 3 } };
var comparer = new Comparer<int[,]>();
var isEqual = comparer.Compare(a1, a2, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsFalse(isEqual);
CollectionAssert.IsNotEmpty(differences);
Assert.AreEqual(1, differences.Count());
Assert.AreEqual("[0,1]", differences.First().MemberPath);
Assert.AreEqual("2", differences.First().Value1);
Assert.AreEqual("3", differences.First().Value2);
}
[Test]
public void MultidimensionalArraysSizeInequality3()
{
var a1 = new[,] { { 1, 2 }, { 1, 3 } };
var a2 = new[,] { { 1, 3, 4 }, { 1, 3, 8 } };
var comparer = new Comparer<int[,]>();
var isEqual = comparer.Compare(a1, a2, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsFalse(isEqual);
CollectionAssert.IsNotEmpty(differences);
Assert.AreEqual(1, differences.Count());
Assert.AreEqual("Dimension1", differences.First().MemberPath);
Assert.AreEqual("2", differences.First().Value1);
Assert.AreEqual("3", differences.First().Value2);
}
#endregion
#region Dynamic objects (ExpandoObject)
[Test]
public void ExpandoObject()
{
dynamic a1 = new ExpandoObject();
a1.Field1 = "A";
a1.Field2 = 5;
a1.Field4 = 4;
dynamic a2 = new ExpandoObject();
a2.Field1 = "B";
a2.Field3 = false;
a2.Field4 = "C";
var comparer = new Comparer();
var isEqual = comparer.Compare(a1, a2, out IEnumerable<Difference> differences);
ResultToOutput(isEqual, differences);
Assert.IsFalse(isEqual);
Assert.AreEqual(4, differences.Count());
Assert.IsTrue(differences.Any(d => d.MemberPath == "Field1" && d.Value1 == "A" && d.Value2 == "B"));
Assert.IsTrue(differences.Any(d => d.DifferenceType == DifferenceTypes.MissedMemberInSecondObject && d.MemberPath == "Field2" && d.Value1 == "5"));
Assert.IsTrue(differences.Any(d => d.DifferenceType == DifferenceTypes.MissedMemberInFirstObject && d.MemberPath == "Field3" && d.Value2 == "False"));
Assert.IsTrue(differences.Any(d => d.DifferenceType == DifferenceTypes.TypeMismatch && d.MemberPath == "Field4" && d.Value1 == "4" && d.Value2 == "C"));
}
[Test]
public void ExpandoObjectWhenMissedFieldsAndUseDefaults()
{
dynamic a1 = new ExpandoObject();
a1.Field1 = "A";
a1.Field2 = 0;
dynamic a2 = new ExpandoObject();
a2.Field1 = "B";
a2.Field3 = false;
a2.Field4 = "S";
var comparer = new Comparer(new ComparisonSettings { UseDefaultIfMemberNotExist = true });
var isEqual = comparer.Compare(a1, a2, out IEnumerable<Difference> differences);
ResultToOutput(isEqual, differences);
Assert.IsFalse(isEqual);
Assert.AreEqual(2, differences.Count());
Assert.IsTrue(differences.Any(d => d.MemberPath == "Field1" && d.Value1 == "A" && d.Value2 == "B"));
Assert.IsTrue(differences.Any(d => d.DifferenceType == DifferenceTypes.ValueMismatch && d.MemberPath == "Field4" && d.Value2 == "S"));
}
#endregion
#region Dynamic objects (DynamicObject)
private class DynamicDictionary : DynamicObject
{
// ReSharper disable once UnusedMember.Local
public int IntProperty { get; set; }
private readonly Dictionary<string, object> _dictionary = new Dictionary<string, object>();
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
var name = binder.Name;
return _dictionary.TryGetValue(name, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
_dictionary[binder.Name] = value;
return true;
}
public override IEnumerable<string> GetDynamicMemberNames()
{
return _dictionary.Keys;
}
}
[Test]
public void DynamicObject()
{
dynamic a1 = new DynamicDictionary();
a1.Field1 = "A";
a1.Field3 = true;
dynamic a2 = new DynamicDictionary();
a2.Field1 = "B";
a2.Field2 = 8;
a2.Field3 = 1;
var comparer = new Comparer();
var isEqual = comparer.Compare(a1, a2, out IEnumerable<Difference> differences);
ResultToOutput(isEqual, differences);
Assert.IsFalse(isEqual);
Assert.AreEqual(3, differences.Count());
Assert.IsTrue(differences.Any(d => d.MemberPath == "Field1" && d.Value1 == "A" && d.Value2 == "B"));
Assert.IsTrue(differences.Any(d => d.DifferenceType == DifferenceTypes.MissedMemberInFirstObject && d.MemberPath == "Field2" && d.Value2 == "8"));
Assert.IsTrue(differences.Any(d => d.DifferenceType == DifferenceTypes.TypeMismatch && d.MemberPath == "Field3" && d.Value1 == "True" && d.Value2 == "1"));
}
#endregion
#region Dynamic objects (compiler generated)
[Test]
public void CompilerGeneratedDynamicObjects()
{
dynamic a1 = new
{
Field1 = "A",
Field2 = 5,
Field3 = true
};
dynamic a2 = new
{
Field1 = "B",
Field2 = 8.0
};
var comparer = new Comparer();
var isEqual = comparer.Compare((object)a1, (object)a2, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsFalse(isEqual);
Assert.AreEqual(3, differences.Count());
Assert.IsTrue(differences.Any(d => d.MemberPath == "Field1" && d.Value1 == "A" && d.Value2 == "B"));
Assert.IsTrue(differences.Any(d => d.DifferenceType == DifferenceTypes.TypeMismatch && d.MemberPath == "Field2" && d.Value1 == "5" && d.Value2 == 8.0.ToString(CultureInfo.InvariantCulture)));
Assert.IsTrue(differences.Any(d => d.DifferenceType == DifferenceTypes.MissedMemberInSecondObject && d.MemberPath == "Field3" && d.Value1 == "True"));
}
#endregion
#region Overrides
public class MyValueComparer : AbstractValueComparer<string>
{
public override bool Compare(string obj1, string obj2, ComparisonSettings settings)
{
return obj1 == obj2; //Implement comparison logic here
}
}
[Test]
public void Overrides()
{
var comparer = new Comparer<ClassA>();
// Type
//Use MyComparer to compare all members of type string
comparer.AddComparerOverride<string>(new MyValueComparer());
comparer.AddComparerOverride(typeof(string), new MyValueComparer());
//Use MyComparer to compare all members of type string except members which name starts with "Xyz"
comparer.AddComparerOverride<string>(new MyValueComparer(), member => !member.Name.StartsWith("Xyz"));
// Member Info
//Use MyValueComparer to compare StringProperty of ClassA
//comparer.AddComparerOverride(() => new ClassA().StringProperty, new MyValueComparer());
//comparer.AddComparerOverride(
// typeof(ClassA).GetTypeInfo().GetMember("StringProperty").First(),
// new MyValueComparer());
//Compare StringProperty of ClassA by length. If length equal consider that values are equal
//comparer.AddComparerOverride(
// () => new ClassA().StringProperty,
// (s1, s2, parentSettings) => s1?.Length == s2?.Length,
// s => s?.ToString());
//comparer.AddComparerOverride(
// () => new ClassA().StringProperty,
// (s1, s2, parentSettings) => s1?.Length == s2?.Length);
// Member filter
//comparer.AddComparerOverride(new MyValueComparer(), m => m.Name == "StringProperty");
// Member Name
comparer.AddComparerOverride("StringProperty", new MyValueComparer());
//Exception
comparer.AddComparerOverride<string>(new MyValueComparer(), member => member.Name.StartsWith("String"));
comparer.AddComparerOverride<string>(DoNotCompareValueComparer.Instance, member => member.Name.EndsWith("Property"));
//var result = comparer.Compare(a1, a2);//Exception here
}
#endregion
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Examples/BasicExamples/ClassA.cs
================================================
namespace ObjectsComparer.Examples.BasicExamples
{
public class ClassA
{
public string StringProperty { get; set; }
public int IntProperty { get; set; }
public SubClassA SubClass { get; set; }
}
public class SubClassA
{
public bool BoolProperty { get; set; }
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Examples/Example1/Error.cs
================================================
namespace ObjectsComparer.Examples.Example1
{
public class Error
{
public int Id { get; set; }
public string Messgae { get; set; }
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Examples/Example1/Example1Tests.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using static ObjectsComparer.Examples.OutputHelper;
// ReSharper disable PossibleMultipleEnumeration
namespace ObjectsComparer.Examples.Example1
{
[TestFixture]
public class Example1Tests
{
private IComparer<Message> _comparer;
[SetUp]
public void SetUp()
{
_comparer = new Comparer<Message>(
new ComparisonSettings
{
//Null and empty error lists are equal
EmptyAndNullEnumerablesEqual = true
});
//Do not compare Dates
_comparer.AddComparerOverride<DateTime>(DoNotCompareValueComparer.Instance);
//Do not compare Id
_comparer.AddComparerOverride(() => new Message().Id, DoNotCompareValueComparer.Instance);
//Do not compare Message Text
_comparer.AddComparerOverride(() => new Error().Messgae, DoNotCompareValueComparer.Instance);
}
[Test]
public void EqualMessagesWithoutErrors()
{
var expectedMessage = new Message
{
MessageType = 1,
Status = 0
};
var actualMessage = new Message
{
Id = "M12345",
DateCreated = DateTime.Now,
DateReceived = DateTime.Now,
DateSent = DateTime.Now,
MessageType = 1,
Status = 0
};
var isEqual = _comparer.Compare(expectedMessage, actualMessage, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsTrue(isEqual);
}
[Test]
public void EqualMessagesWithErrors()
{
var expectedMessage = new Message
{
MessageType = 1,
Status = 1,
Errors = new List<Error>
{
new Error { Id = 2 },
new Error { Id = 7 }
}
};
var actualMessage = new Message
{
Id = "M12345",
DateCreated = DateTime.Now,
DateReceived = DateTime.Now,
DateSent = DateTime.Now,
MessageType = 1,
Status = 1,
Errors = new List<Error>
{
new Error { Id = 2, Messgae = "Some error #2" },
new Error { Id = 7, Messgae = "Some error #7" }
}
};
var isEqual = _comparer.Compare(expectedMessage, actualMessage, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsTrue(isEqual);
}
[Test]
public void UnequalMessages()
{
var expectedMessage = new Message
{
MessageType = 1,
Status = 1,
Errors = new List<Error>
{
new Error { Id = 2, Messgae = "Some error #2" },
new Error { Id = 8, Messgae = "Some error #8" }
}
};
var actualMessage = new Message
{
Id = "M12345",
DateCreated = DateTime.Now,
DateReceived = DateTime.Now,
DateSent = DateTime.Now,
MessageType = 1,
Status = 2,
Errors = new List<Error>
{
new Error { Id = 2, Messgae = "Some error #2" },
new Error { Id = 7, Messgae = "Some error #7" }
}
};
var isEqual = _comparer.Compare(expectedMessage, actualMessage, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsFalse(isEqual);
Assert.AreEqual(2, differences.Count());
Assert.IsTrue(differences.Any(d => d.MemberPath == "Status" && d.Value1 == "1" && d.Value2 == "2"));
Assert.IsTrue(differences.Any(d => d.MemberPath == "Errors[1].Id" && d.Value1 == "8" && d.Value2 == "7"));
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Examples/Example1/Message.cs
================================================
using System;
using System.Collections.Generic;
namespace ObjectsComparer.Examples.Example1
{
public class Message
{
public string Id { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateSent { get; set; }
public DateTime DateReceived { get; set; }
public int MessageType { get; set; }
public int Status { get; set; }
public List<Error> Errors { get; set; }
public override string ToString()
{
return $"Id:{Id}, Type:{MessageType}, Status:{Status}";
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Examples/Example2/Example2Tests.cs
================================================
using System;
using System.Linq;
using NUnit.Framework;
using static ObjectsComparer.Examples.OutputHelper;
// ReSharper disable PossibleMultipleEnumeration
namespace ObjectsComparer.Examples.Example2
{
[TestFixture]
public class Example2Tests
{
private MyComparersFactory _factory;
private IComparer<Person> _comparer;
[SetUp]
public void SetUp()
{
_factory = new MyComparersFactory();
_comparer = _factory.GetObjectsComparer<Person>();
}
[Test]
public void EqualPersonsTest()
{
var person1 = new Person
{
PersonId = Guid.NewGuid(),
FirstName = "John",
LastName = "Doe",
MiddleName = "F",
PhoneNumber = "111-555-8888"
};
var person2 = new Person
{
PersonId = Guid.NewGuid(),
FirstName = "John",
LastName = "Doe",
PhoneNumber = "(111) 555 8888"
};
var isEqual = _comparer.Compare(person1, person2, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsTrue(isEqual);
}
[Test]
public void DifferentPersonsTest()
{
var person1 = new Person
{
PersonId = Guid.NewGuid(),
FirstName = "Jack",
LastName = "Doe",
MiddleName = "F",
PhoneNumber = "111-555-8888"
};
var person2 = new Person
{
PersonId = Guid.NewGuid(),
FirstName = "John",
LastName = "Doe",
MiddleName = "L",
PhoneNumber = "222-555-9999"
};
var isEqual = _comparer.Compare(person1, person2, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsFalse(isEqual);
Assert.AreEqual(3, differences.Count());
Assert.IsTrue(differences.Any(d => d.MemberPath == "FirstName" && d.Value1 == "Jack" && d.Value2 == "John"));
Assert.IsTrue(differences.Any(d => d.MemberPath == "MiddleName" && d.Value1 == "F" && d.Value2 == "L"));
Assert.IsTrue(differences.Any(d => d.MemberPath == "PhoneNumber" && d.Value1 == "111-555-8888" && d.Value2 == "222-555-9999"));
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Examples/Example2/MyComparersFactory.cs
================================================
using System;
namespace ObjectsComparer.Examples.Example2
{
public class MyComparersFactory : ComparersFactory
{
public override IComparer<T> GetObjectsComparer<T>(ComparisonSettings settings = null,
BaseComparer parentComparer = null)
{
if (typeof(T) != typeof(Person))
{
return base.GetObjectsComparer<T>(settings, parentComparer);
}
var comparer = new Comparer<Person>(settings, parentComparer, this);
//Do not compare PersonId
comparer.AddComparerOverride<Guid>(DoNotCompareValueComparer.Instance);
//Sometimes MiddleName can be skipped. Compare only if property has value.
comparer.AddComparerOverride(
() => new Person().MiddleName,
(s1, s2, parentSettings) => string.IsNullOrWhiteSpace(s1) || string.IsNullOrWhiteSpace(s2) || s1 == s2);
comparer.AddComparerOverride(
() => new Person().PhoneNumber,
new PhoneNumberComparer());
return (IComparer<T>) comparer;
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Examples/Example2/Person.cs
================================================
using System;
namespace ObjectsComparer.Examples.Example2
{
public class Person
{
public Guid PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string MiddleName { get; set; }
public string PhoneNumber { get; set; }
public override string ToString()
{
return $"{FirstName} {MiddleName} {LastName} ({PhoneNumber})";
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Examples/Example2/PhoneNumberComparer.cs
================================================
using System.Linq;
namespace ObjectsComparer.Examples.Example2
{
public class PhoneNumberComparer: AbstractValueComparer<string>
{
public override bool Compare(string obj1, string obj2, ComparisonSettings settings)
{
return ExtractDigits(obj1) == ExtractDigits(obj2);
}
private string ExtractDigits(string str)
{
return string.Join(
string.Empty,
(str ?? string.Empty)
.ToCharArray()
.Where(char.IsDigit));
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Examples/Example3/Example3Tests.cs
================================================
using System;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using Newtonsoft.Json;
using NUnit.Framework;
using static ObjectsComparer.Examples.OutputHelper;
// ReSharper disable PossibleMultipleEnumeration
namespace ObjectsComparer.Examples.Example3
{
[TestFixture]
public class Example3Tests
{
private Comparer _comparer;
[SetUp]
public void SetUp()
{
_comparer = new Comparer(new ComparisonSettings { UseDefaultIfMemberNotExist = true });
//Some fields should be ignored
_comparer.AddComparerOverride("ConnectionString", DoNotCompareValueComparer.Instance);
_comparer.AddComparerOverride("Email", DoNotCompareValueComparer.Instance);
_comparer.AddComparerOverride("Notifications", DoNotCompareValueComparer.Instance);
//Smart Modes are disabled by default. These fields are not case sensitive
var disabledByDefaultComparer = new DefaultValueValueComparer<string>("Disabled", IgnoreCaseStringsValueComparer.Instance);
_comparer.AddComparerOverride("SmartMode1", disabledByDefaultComparer);
_comparer.AddComparerOverride("SmartMode2", disabledByDefaultComparer);
_comparer.AddComparerOverride("SmartMode3", disabledByDefaultComparer);
//http prefix in URLs should be ignored
var urlComparer = new DynamicValueComparer<string>(
(url1, url2, settings) => url1.Trim('/').Replace(@"http://", string.Empty) == url2.Trim('/').Replace(@"http://", string.Empty));
_comparer.AddComparerOverride("SomeUrl", urlComparer);
_comparer.AddComparerOverride("SomeOtherUrl", urlComparer);
//DataCompression is Off by default.
_comparer.AddComparerOverride("DataCompression", new DefaultValueValueComparer<string>("Off", NulableStringsValueComparer.Instance));
//ProcessTaskTimeout and TotalProcessTimeout fields have default values.
_comparer.AddComparerOverride("ProcessTaskTimeout", new DefaultValueValueComparer<long>(100, DefaultValueComparer.Instance));
_comparer.AddComparerOverride("TotalProcessTimeout", new DefaultValueValueComparer<long>(500, DefaultValueComparer.Instance));
}
[Test]
public void Settings1()
{
var settings0Json = LoadJson("Settings0.json");
var settings0 = JsonConvert.DeserializeObject<ExpandoObject>(settings0Json);
var settings1Json = LoadJson("Settings1.json");
var settings1 = JsonConvert.DeserializeObject<ExpandoObject>(settings1Json);
var isEqual = _comparer.Compare(settings0, settings1, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsTrue(isEqual);
}
[Test]
public void Settings2()
{
var settings0Json = LoadJson("Settings0.json");
var settings0 = JsonConvert.DeserializeObject<ExpandoObject>(settings0Json);
var settings2Json = LoadJson("Settings2.json");
var settings2 = JsonConvert.DeserializeObject<ExpandoObject>(settings2Json);
var isEqual = _comparer.Compare(settings0, settings2, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsFalse(isEqual);
Assert.AreEqual(8, differences.Count());
Assert.IsTrue(differences.Any(d => d.MemberPath == "Settings.DataCompression" && d.Value1 == "On" && d.Value2 == "Off"));
Assert.IsTrue(differences.Any(d => d.MemberPath == "Settings.SuperModes.SmartMode1" && d.Value1 == "Enabled" && d.Value2 == "Disabled"));
Assert.IsTrue(differences.Any(d => d.MemberPath == "Timeouts.ProcessTaskTimeout" && d.Value1 == "100" && d.Value2 == "200"));
Assert.IsTrue(differences.Any(d => d.MemberPath == "BackupSettings.BackupIntervalUnit" && d.Value1 == "Day" && d.Value2 == "Week"));
Assert.IsTrue(differences.Any(d => d.MemberPath == "BackupSettings.BackupInterval" && d.Value1 == "100" && d.Value2 == "2"));
Assert.IsTrue(differences.Any(d => d.MemberPath == "Logging.Enabled" && d.Value1 == "True" && d.Value2 == "False"));
Assert.IsTrue(differences.Any(d => d.MemberPath == "Logging.MaximumFileSize" && d.Value1 == "20MB" && d.Value2 == "40MB"));
Assert.IsTrue(differences.Any(d => d.MemberPath == "Logging.Level" && d.Value1 == "ALL" && d.Value2 == "ERROR"));
}
private string LoadJson(string fileName)
{
var resourceStream = typeof(Example3Tests).GetTypeInfo()
.Assembly.GetManifestResourceStream("ObjectsComparer.Examples.Example3." + fileName);
if (resourceStream == null)
{
throw new Exception($"Resource '{fileName}' not found");
}
using (var reader = new StreamReader(resourceStream, Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Examples/Example3/Settings0.json
================================================
{
"ConnectionString": "USER ID=superuser;PASSWORD=superpassword;DATA SOURCE=localhost:1111",
"Email": {
"Port": 25,
"Host": "MyHost.com",
"EmailAddress": "test@MyHost.com"
},
"Settings": {
"DataCompression": "On",
"DataSourceType": "MultiDataSource",
"SomeUrl": "http://MyHost.com/VeryImportantData",
"SomeOtherUrl": "http://MyHost.com/NotSoImportantData/",
"CacheMode": "Memory",
"MaxCacheSize": "1GB",
"SuperModes": {
"SmartMode1": "Enabled",
"SmartMode2": "Disabled",
"SmartMode3": "Enabled"
}
},
"Timeouts": {
"TotalProcessTimeout": 500,
"ProcessTaskTimeout": 100
},
"BackupSettings": {
"BackupIntervalUnit": "Day",
"BackupInterval": 100
},
"Notifications": [
{
"Phone": "111-222-3333"
},
{
"Phone": "111-222-4444"
},
{
"EMail": "support@MyHost.com"
}
],
"Logging": {
"Enabled": true,
"Pattern": "Logs\\MyApplication.%data{yyyyMMdd}.log",
"MaximumFileSize": "20MB",
"Level": "ALL"
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Examples/Example3/Settings1.json
================================================
{
"ConnectionString": "USER ID=admin;PASSWORD=*****;DATA SOURCE=localhost:22222",
"Email": {
"Port": 25,
"Host": "MyHost.com",
"EmailAddress": "test@MyHost.com"
},
"Settings": {
"DataCompression": "On",
"DataSourceType": "MultiDataSource",
"SomeUrl": "MyHost.com/VeryImportantData",
"SomeOtherUrl": "MyHost.com/NotSoImportantData/",
"CacheMode": "Memory",
"MaxCacheSize": "1GB",
"SuperModes": {
"SmartMode1": "enabled",
"SmartMode3": "enabled"
}
},
"BackupSettings": {
"BackupIntervalUnit": "Day",
"BackupInterval": 100
},
"Notifications": [
{
"Phone": "111-222-3333"
},
{
"EMail": "support@MyHost.com"
}
],
"Logging": {
"Enabled": true,
"Pattern": "Logs\\MyApplication.%data{yyyyMMdd}.log",
"MaximumFileSize": "20MB",
"Level": "ALL"
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Examples/Example3/Settings2.json
================================================
{
"ConnectionString": "USER ID=superuser;PASSWORD=superpassword;DATA SOURCE=localhost:1111",
"Email": {
"Port": 25,
"Host": "MyHost.com",
"EmailAddress": "test@MyHost.com"
},
"Settings": {
"DataSourceType": "MultiDataSource",
"SomeUrl": "http://MyHost.com/VeryImportantData",
"SomeOtherUrl": "http://MyHost.com/NotSoImportantData/",
"CacheMode": "Memory",
"MaxCacheSize": "1GB",
"SuperModes": {
"SmartMode3": "Enabled"
}
},
"Timeouts": {
"TotalProcessTimeout": 500,
"ProcessTaskTimeout": 200
},
"BackupSettings": {
"BackupIntervalUnit": "Week",
"BackupInterval": 2
},
"Notifications": [
{
"EMail": "support@MyHost.com"
}
],
"Logging": {
"Enabled": false,
"Pattern": "Logs\\MyApplication.%data{yyyyMMdd}.log",
"MaximumFileSize": "40MB",
"Level": "ERROR"
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Examples/Example4/CustomFormulaItemsComparer.cs
================================================
using System.Collections.Generic;
using System.Linq;
namespace ObjectsComparer.Examples.Example4
{
public class CustomFormulaItemsComparer: AbstractComparer<IList<FormulaItem>>
{
public CustomFormulaItemsComparer(ComparisonSettings settings, BaseComparer parentComparer, IComparersFactory factory) : base(settings, parentComparer, factory)
{
}
public override IEnumerable<Difference> CalculateDifferences(IList<FormulaItem> obj1, IList<FormulaItem> obj2)
{
if (obj1 == null && obj2 == null)
{
yield break;
}
if (obj1 == null || obj2 == null)
{
yield return new Difference("", DefaultValueComparer.ToString(obj1) , DefaultValueComparer.ToString(obj2));
yield break;
}
if (obj1.Count != obj2.Count)
{
yield return new Difference("Count", obj1.Count.ToString(), obj2.Count.ToString(),
DifferenceTypes.NumberOfElementsMismatch);
}
foreach (var formulaItem in obj1)
{
var formulaItem2 = obj2.FirstOrDefault(fi => fi.Id == formulaItem.Id);
if (formulaItem2 != null)
{
var comparer = Factory.GetObjectsComparer<FormulaItem>();
foreach (var difference in comparer.CalculateDifferences(formulaItem, formulaItem2))
{
yield return difference.InsertPath($"[Id={formulaItem.Id}]");
}
}
}
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Examples/Example4/Example4Tests.cs
================================================
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using static ObjectsComparer.Examples.OutputHelper;
// ReSharper disable PossibleMultipleEnumeration
namespace ObjectsComparer.Examples.Example4
{
[TestFixture]
public class Example4Tests
{
private MyComparersFactory _factory;
private IComparer<Formula> _comparer;
[SetUp]
public void SetUp()
{
_factory = new MyComparersFactory();
_comparer = _factory.GetObjectsComparer<Formula>();
}
[Test]
public void List_Of_Equal_Sizes_But_Is_Inequality()
{
var formula1 = new Formula
{
Id = 1,
Name = "Formula 1",
Items = new List<FormulaItem>
{
new FormulaItem
{
Id = 1,
Delay = 60,
Name = "Item 1",
Instruction = "Instruction 1"
}
}
};
var formula2 = new Formula
{
Id = 1,
Name = "Formula 1",
Items = new List<FormulaItem>
{
new FormulaItem
{
Id = 1,
Delay = 80,
Name = "Item One",
Instruction = "Instruction One"
}
}
};
var isEqual = _comparer.Compare(formula1, formula2, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsFalse(isEqual);
Assert.AreEqual(3, differences.Count());
Assert.IsTrue(differences.Any(d => d.MemberPath == "Items[Id=1].Delay" && d.Value1 == "60" && d.Value2 == "80"));
Assert.IsTrue(differences.Any(d => d.MemberPath == "Items[Id=1].Name" && d.Value1 == "Item 1" && d.Value2 == "Item One"));
Assert.IsTrue(differences.Any(d => d.MemberPath == "Items[Id=1].Instruction" && d.Value1 == "Instruction 1" && d.Value2 == "Instruction One"));
}
[Test]
public void List_Of_Different_Sizes_But_Is_Inequality()
{
var formula1 = new Formula
{
Id = 1,
Name = "Formula 1",
Items = new List<FormulaItem>
{
new FormulaItem
{
Id = 1,
Delay = 60,
Name = "Item 1",
Instruction = "Instruction 1"
}
}
};
var formula2 = new Formula
{
Id = 1,
Name = "Formula 1",
Items = new List<FormulaItem>
{
new FormulaItem
{
Id = 1,
Delay = 80,
Name = "Item One",
Instruction = "Instruction One"
},
new FormulaItem
{
Id = 2,
Delay = 30,
Name = "Item Two",
Instruction = "Instruction Two"
}
}
};
var isEqual = _comparer.Compare(formula1, formula2, out var differences);
ResultToOutput(isEqual, differences);
Assert.IsFalse(isEqual);
Assert.AreEqual(4, differences.Count());
Assert.IsTrue(differences.Any(d => d.MemberPath == "Items.Count" && d.Value1 == "1" && d.Value2 == "2"));
Assert.IsTrue(differences.Any(d => d.MemberPath == "Items[Id=1].Delay" && d.Value1 == "60" && d.Value2 == "80"));
Assert.IsTrue(differences.Any(d => d.MemberPath == "Items[Id=1].Name" && d.Value1 == "Item 1" && d.Value2 == "Item One"));
Assert.IsTrue(differences.Any(d => d.MemberPath == "Items[Id=1].Instruction" && d.Value1 == "Instruction 1" && d.Value2 == "Instruction One"));
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Examples/Example4/Formula.cs
================================================
using System.Collections.Generic;
namespace ObjectsComparer.Examples.Example4
{
public class Formula
{
public long Id { get; set; }
public string Name { get; set; }
public IList<FormulaItem> Items { get; set; }
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Examples/Example4/FormulaItem.cs
================================================
namespace ObjectsComparer.Examples.Example4
{
public class FormulaItem
{
public long Id { get; set; }
public int Delay { get; set; }
public string Name { get; set; }
public string Instruction { get; set; }
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Examples/Example4/MyComparersFactory.cs
================================================
using System.Collections.Generic;
namespace ObjectsComparer.Examples.Example4
{
public class MyComparersFactory : ComparersFactory
{
public override IComparer<T> GetObjectsComparer<T>(ComparisonSettings settings = null,
BaseComparer parentComparer = null)
{
if (typeof(T) != typeof(IList<FormulaItem>))
{
return base.GetObjectsComparer<T>(settings, parentComparer);
}
var comparer = new CustomFormulaItemsComparer(settings, parentComparer, this);
return (IComparer<T>) comparer;
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Examples/Example5/Error.cs
================================================
namespace ObjectsComparer.Examples.Example5
{
public class Error
{
[Ignore]
public int Id { get; set; }
public string Messgae { get; set; }
[Ignore]
public string Details { get; set; }
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Examples/Example5/Example5Tests.cs
================================================
using NUnit.Framework;
namespace ObjectsComparer.Examples.Example5
{
[TestFixture]
public class Example5Tests
{
[Test]
public void IgnoreByAttribute()
{
var error1 = new Error
{
Id = 1,
Messgae = "Error Message",
Details = "Error details"
};
var error2 = new Error
{
Id = 2,
Messgae = "Error Message",
Details = "Other error details"
};
var comparer = new Comparer<Error>();
comparer.IgnoreMember(m => m.GetCustomAttributes(typeof(IgnoreAttribute), true).Length > 0);
var isEqual = comparer.Compare(error1, error2);
Assert.IsTrue(isEqual);
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Examples/Example5/IgnoreAttribute.cs
================================================
using System;
namespace ObjectsComparer.Examples.Example5
{
[AttributeUsage(AttributeTargets.Property)]
public class IgnoreAttribute: Attribute
{
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Examples/ObjectsComparer.Examples.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp2.0;net45</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<None Remove="Example3\Settings0.json" />
<None Remove="Example3\Settings1.json" />
<None Remove="Example3\Settings2.json" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Example3\Settings0.json">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Example3\Settings1.json">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
<EmbeddedResource Include="Example3\Settings2.json">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="NUnit" Version="3.10.1" />
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ObjectsComparer\ObjectsComparer.csproj" />
</ItemGroup>
</Project>
================================================
FILE: ObjectsComparer/ObjectsComparer.Examples/OutputHelper.cs
================================================
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace ObjectsComparer.Examples
{
public static class OutputHelper
{
public static void ResultToOutput(bool isEqual, IEnumerable<Difference> differenses)
{
Debug.WriteLine(isEqual ? "Objects are equal" : string.Join(Environment.NewLine, differenses));
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Tests/AbstractComparerGenericTests.cs
================================================
using System.Collections.Generic;
using NSubstitute;
using NUnit.Framework;
namespace ObjectsComparer.Tests
{
[TestFixture]
public class AbstractComparerGenericTests
{
private BaseComparer _parentComparerMock;
private IComparersFactory _factoryMock;
private AbstractComparer<int> _comparer;
[SetUp]
public void SetUp()
{
_factoryMock = Substitute.For<IComparersFactory>();
_parentComparerMock = Substitute.ForPartsOf<BaseComparer>(new ComparisonSettings(), null, _factoryMock);
_comparer =
Substitute.ForPartsOf<AbstractComparer<int>>(new ComparisonSettings(), _parentComparerMock, _factoryMock);
}
[Test]
public void CalculateDifferences()
{
_comparer.CalculateDifferences(1, 2);
_comparer.Received().CalculateDifferences(1, 2);
}
[Test]
public void CompareWithOutParameterWhenNotEqual()
{
var differences = new List<Difference> { new Difference("", "1", "2") };
_comparer.CalculateDifferences(1, 2).Returns(differences);
var result = _comparer.Compare(1, 2, out var outDifferences);
Assert.IsFalse(result);
_comparer.Received().CalculateDifferences(1, 2);
Assert.AreEqual(differences, outDifferences);
}
[Test]
public void CompareWithOutParameterWhenEqual()
{
var differences = new List<Difference>();
_comparer.CalculateDifferences(1, 1).Returns(differences);
var result = _comparer.Compare(1, 1, out var outDifferences);
Assert.IsTrue(result);
_comparer.Received().CalculateDifferences(1, 1);
Assert.AreEqual(differences, outDifferences);
}
[Test]
public void CompareWithoutOutParameterWhenNotEqual()
{
var differences = new List<Difference> { new Difference("", "1", "2") };
_comparer.CalculateDifferences(1, 2).Returns(differences);
var result = _comparer.Compare(1, 2);
Assert.IsFalse(result);
_comparer.Received().CalculateDifferences(1, 2);
}
[Test]
public void CompareWithoutOutParameterWhenEqual()
{
_comparer.CalculateDifferences(1, 2).Returns(new List<Difference>());
var result = _comparer.Compare(1, 2);
Assert.IsTrue(result);
_comparer.Received().CalculateDifferences(1, 2);
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Tests/AbstractComparerTests.cs
================================================
using System.Collections.Generic;
using NSubstitute;
using NUnit.Framework;
namespace ObjectsComparer.Tests
{
[TestFixture]
public class AbstractComparerTests
{
private BaseComparer _parentComparerMock;
private IComparersFactory _factoryMock;
private AbstractComparer _comparer;
[SetUp]
public void SetUp()
{
_factoryMock = Substitute.For<IComparersFactory>();
_parentComparerMock = Substitute.ForPartsOf<BaseComparer>(new ComparisonSettings(), null, _factoryMock);
_comparer =
Substitute.ForPartsOf<AbstractComparer>(new ComparisonSettings(), _parentComparerMock, _factoryMock);
}
[Test]
public void CalculateDifferences()
{
_comparer.CalculateDifferences("string1", "string2");
_comparer.Received().CalculateDifferences(typeof(string), "string1", "string2");
}
[Test]
public void CompareWithOutParameterWhenNotEqual()
{
var differences = new List<Difference> {new Difference("", "string1", "string2")};
_comparer.CalculateDifferences(typeof(string), "string1", "string2").Returns(differences);
var result = _comparer.Compare("string1", "string2", out var outDifferences);
Assert.IsFalse(result);
_comparer.Received().CalculateDifferences(typeof(string), "string1", "string2");
Assert.AreEqual(differences, outDifferences);
}
[Test]
public void CompareWithOutParameterWhenEqual()
{
var differences = new List<Difference>();
_comparer.CalculateDifferences(typeof(string), "string1", "string1").Returns(differences);
var result = _comparer.Compare("string1", "string1", out var outDifferences);
Assert.IsTrue(result);
_comparer.Received().CalculateDifferences(typeof(string), "string1", "string1");
Assert.AreEqual(differences, outDifferences);
}
[Test]
public void CompareWithoutOutParameterWhenNotEqual()
{
var differences = new List<Difference> {new Difference("", "string1", "string2")};
_comparer.CalculateDifferences(typeof(string), "string1", "string2").Returns(differences);
var result = _comparer.Compare("string1", "string2");
Assert.IsFalse(result);
_comparer.Received().CalculateDifferences(typeof(string), "string1", "string2");
}
[Test]
public void CompareWithoutOutParameterWhenEqual()
{
_comparer.CalculateDifferences(typeof(string), "string1", "string2").Returns(new List<Difference>());
var result = _comparer.Compare("string1", "string2");
Assert.IsTrue(result);
_comparer.Received().CalculateDifferences(typeof(string), "string1", "string2");
}
[Test]
public void NonGenericCompareWithOutParameterWhenNotEqual()
{
var differences = new List<Difference> {new Difference("", "string1", "string2")};
_comparer.CalculateDifferences(typeof(string), "string1", "string2").Returns(differences);
var result = _comparer.Compare(typeof(string), "string1", "string2", out var outDifferences);
Assert.IsFalse(result);
_comparer.Received().CalculateDifferences(typeof(string), "string1", "string2");
Assert.AreEqual(differences, outDifferences);
}
[Test]
public void NonGenericCompareWithOutParameterWhenEqual()
{
var differences = new List<Difference>();
_comparer.CalculateDifferences(typeof(string), "string1", "string1").Returns(differences);
var result = _comparer.Compare(typeof(string), "string1", "string1", out var outDifferences);
Assert.IsTrue(result);
_comparer.Received().CalculateDifferences(typeof(string), "string1", "string1");
Assert.AreEqual(differences, outDifferences);
}
[Test]
public void NonGenericCompareWithoutOutParameterWhenNotEqual()
{
var differences = new List<Difference> {new Difference("", "string1", "string2")};
_comparer.CalculateDifferences(typeof(string), "string1", "string2").Returns(differences);
var result = _comparer.Compare(typeof(string), "string1", "string2");
Assert.IsFalse(result);
_comparer.Received().CalculateDifferences(typeof(string), "string1", "string2");
}
[Test]
public void NonGenericCompareWithoutOutParameterWhenEqual()
{
_comparer.CalculateDifferences(typeof(string), "string1", "string2").Returns(new List<Difference>());
var result = _comparer.Compare(typeof(string), "string1", "string2");
Assert.IsTrue(result);
_comparer.Received().CalculateDifferences(typeof(string), "string1", "string2");
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Tests/ComparerNonGenericTests.cs
================================================
using System;
using System.Linq;
using NUnit.Framework;
using ObjectsComparer.Tests.TestClasses;
namespace ObjectsComparer.Tests
{
[TestFixture]
public class ComparerNonGenericTests
{
[Test]
public void PropertyEquality()
{
var a1 = new A { IntProperty = 10, DateTimeProperty = new DateTime(2017, 1, 1), Property3 = 5 };
var a2 = new A { IntProperty = 10, DateTimeProperty = new DateTime(2017, 1, 1), Property3 = 8 };
var comparer = new Comparer();
var isEqual = comparer.Compare(a1, a2);
Assert.IsTrue(isEqual);
}
[Test]
public void PropertyInequality()
{
var date1 = new DateTime(2017, 1, 1);
var date2 = new DateTime(2017, 1, 2);
var a1 = new A { IntProperty = 10, DateTimeProperty = date1 };
var a2 = new A { IntProperty = 8, DateTimeProperty = date2 };
var comparer = new Comparer();
var differences = comparer.CalculateDifferences(a1, a2).ToList();
CollectionAssert.IsNotEmpty(differences);
Assert.AreEqual("IntProperty", differences[0].MemberPath);
Assert.AreEqual("10", differences[0].Value1);
Assert.AreEqual("8", differences[0].Value2);
Assert.AreEqual("DateTimeProperty", differences[1].MemberPath);
// ReSharper disable once SpecifyACultureInStringConversionExplicitly
Assert.AreEqual(date1.ToString(), differences[1].Value1);
// ReSharper disable once SpecifyACultureInStringConversionExplicitly
Assert.AreEqual(date2.ToString(), differences[1].Value2);
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Tests/ComparerOverridesCollectionTests.cs
================================================
using System;
using System.Reflection;
using NSubstitute;
using NUnit.Framework;
using ObjectsComparer.Exceptions;
namespace ObjectsComparer.Tests
{
[TestFixture]
public class ComparerOverridesCollectionTests
{
[Test]
public void AddComparerByMemberInfoWhenMemberNull()
{
var valueComparer = Substitute.For<IValueComparer>();
var collection = new ComparerOverridesCollection();
// ReSharper disable once RedundantCast
Assert.Throws<ArgumentNullException>(() => collection.AddComparer((MemberInfo)null, valueComparer));
}
[Test]
public void AddComparerByMemberInfoWhenComparerNull()
{
var memberInfo = Substitute.ForPartsOf<MemberInfo>();
var collection = new ComparerOverridesCollection();
Assert.Throws<ArgumentNullException>(() => collection.AddComparer(memberInfo, null));
}
[Test]
public void AddComparerByMemberInfoWhenExists()
{
var memberInfo = Substitute.ForPartsOf<MemberInfo>();
var valueComparer = Substitute.For<IValueComparer>();
var collection = new ComparerOverridesCollection();
collection.AddComparer(memberInfo, valueComparer);
var exception = Assert.Throws<ValueComparerExistsException>(() => collection.AddComparer(memberInfo, valueComparer));
Assert.AreEqual(memberInfo, exception.MemberInfo);
}
[Test]
public void GetOverrideByMemberInfoComparer()
{
var memberInfo1 = Substitute.ForPartsOf<PropertyInfo>();
memberInfo1.PropertyType.Returns(typeof(string));
var valueComparer1 = Substitute.For<IValueComparer>();
var memberInfo2 = Substitute.ForPartsOf<PropertyInfo>();
memberInfo2.PropertyType.Returns(typeof(string));
var valueComparer2 = Substitute.For<IValueComparer>();
var collection = new ComparerOverridesCollection();
collection.AddComparer(memberInfo1, valueComparer1);
collection.AddComparer(memberInfo2, valueComparer2);
var valueComparer1FromCollection = collection.GetComparer(memberInfo1);
var valueComparer2FromCollection = collection.GetComparer(memberInfo2);
Assert.AreEqual(valueComparer1, valueComparer1FromCollection);
Assert.AreEqual(valueComparer2, valueComparer2FromCollection);
}
[Test]
public void GetComparerByMemberInfoWhenNotExists()
{
var memberInfo1 = Substitute.ForPartsOf<PropertyInfo>();
memberInfo1.PropertyType.Returns(typeof(string));
var valueComparer1 = Substitute.For<IValueComparer>();
var memberInfo2 = Substitute.ForPartsOf<PropertyInfo>();
memberInfo2.PropertyType.Returns(typeof(string));
var collection = new ComparerOverridesCollection();
collection.AddComparer(memberInfo1, valueComparer1);
var valueComparer2FromCollection = collection.GetComparer(memberInfo2);
Assert.IsNull(valueComparer2FromCollection);
}
[Test]
public void AddComparerByTypeWhenTypeNull()
{
var valueComparer = Substitute.For<IValueComparer>();
var collection = new ComparerOverridesCollection();
Assert.Throws<ArgumentNullException>(() => collection.AddComparer((Type)null, valueComparer));
}
[Test]
public void AddComparerByTypeWhenComparerNull()
{
var collection = new ComparerOverridesCollection();
Assert.Throws<ArgumentNullException>(() => collection.AddComparer(typeof(string), null));
}
[Test]
public void GetOverrideByTypeComparerByMemberInfo()
{
var valueComparer = Substitute.For<IValueComparer>();
var collection = new ComparerOverridesCollection();
var memberInfo = Substitute.ForPartsOf<PropertyInfo>();
memberInfo.PropertyType.Returns(typeof(string));
collection.AddComparer(typeof(string), valueComparer);
var valueComparerFromCollection = collection.GetComparer(memberInfo);
Assert.AreEqual(valueComparer, valueComparerFromCollection);
}
[Test]
public void GetOverrideByTypeComparerByType()
{
var valueComparer = Substitute.For<IValueComparer>();
var collection = new ComparerOverridesCollection();
var memberInfo = Substitute.ForPartsOf<PropertyInfo>();
memberInfo.PropertyType.Returns(typeof(string));
collection.AddComparer(typeof(string), valueComparer);
var valueComparerFromCollection = collection.GetComparer(typeof(string));
Assert.AreEqual(valueComparer, valueComparerFromCollection);
}
[Test]
public void GetComparerByTypeWhenNull()
{
var collection = new ComparerOverridesCollection();
Assert.Throws<ArgumentNullException>(() => collection.GetComparer((Type)null));
}
[Test]
public void GetOverrideByTypeComparerWhenTwoComparersMatchCriteria()
{
var valueComparer1 = Substitute.For<IValueComparer>();
var valueComparer2 = Substitute.For<IValueComparer>();
var collection = new ComparerOverridesCollection();
var memberInfo = Substitute.ForPartsOf<PropertyInfo>();
memberInfo.PropertyType.Returns(typeof(string));
memberInfo.Name.Returns("Prop1");
collection.AddComparer(typeof(string), valueComparer1);
collection.AddComparer(typeof(string), valueComparer2, mi => mi.Name == "Prop1");
var exception = Assert.Throws<AmbiguousComparerOverrideResolutionException>(() => collection.GetComparer(memberInfo));
Assert.AreEqual(memberInfo, exception.MemberInfo);
Assert.AreEqual("Prop1", exception.MemberName);
}
[Test]
public void GetOverrideByTypeComparerWhenOneComparerMatchCriteria()
{
var valueComparer1 = Substitute.For<IValueComparer>();
var valueComparer2 = Substitute.For<IValueComparer>();
var collection = new ComparerOverridesCollection();
var memberInfo = Substitute.ForPartsOf<PropertyInfo>();
memberInfo.PropertyType.Returns(typeof(string));
memberInfo.Name.Returns("Prop1");
collection.AddComparer(typeof(string), valueComparer1, mi => mi.Name == "Prop1");
collection.AddComparer(typeof(string), valueComparer2, mi => mi.Name == "Prop2");
var valueComparerFromCollection = collection.GetComparer(memberInfo);
Assert.AreEqual(valueComparer1, valueComparerFromCollection);
}
[Test]
public void GetOverrideByTypeComparerWhenNoComparerMatchCriteria()
{
var valueComparer1 = Substitute.For<IValueComparer>();
var valueComparer2 = Substitute.For<IValueComparer>();
var collection = new ComparerOverridesCollection();
var memberInfo = Substitute.ForPartsOf<PropertyInfo>();
memberInfo.PropertyType.Returns(typeof(string));
memberInfo.Name.Returns("Prop1");
collection.AddComparer(typeof(string), valueComparer1, mi => false);
collection.AddComparer(typeof(string), valueComparer2, mi => false);
var valueComparerFromCollection = collection.GetComparer(memberInfo);
Assert.IsNull(valueComparerFromCollection);
}
[Test]
public void GetOverrideByTypeWhenOnlyOneComparerDoNotHaveFilter()
{
var valueComparer1 = Substitute.For<IValueComparer>();
var valueComparer2 = Substitute.For<IValueComparer>();
var collection = new ComparerOverridesCollection();
collection.AddComparer(typeof(string), valueComparer1, mi => true);
collection.AddComparer(typeof(string), valueComparer2);
var valueComparerFromCollection = collection.GetComparer(typeof(string));
Assert.AreEqual(valueComparer2, valueComparerFromCollection);
}
[Test]
public void GetOverrideByTypeWhenMoreThanOneComparerMatchCriteria()
{
var valueComparer1 = Substitute.For<IValueComparer>();
var valueComparer2 = Substitute.For<IValueComparer>();
var collection = new ComparerOverridesCollection();
collection.AddComparer(typeof(string), valueComparer1);
collection.AddComparer(typeof(string), valueComparer2);
var exception = Assert.Throws<AmbiguousComparerOverrideResolutionException>(() => collection.GetComparer(typeof(string)));
Assert.AreEqual(typeof(string), exception.Type);
}
[Test]
public void GetOverrideByTypeWhenNoComparerMatchCriteria()
{
var valueComparer1 = Substitute.For<IValueComparer>();
var collection = new ComparerOverridesCollection();
collection.AddComparer(typeof(string), valueComparer1);
var valueComparerFromCollection = collection.GetComparer(typeof(int));
Assert.IsNull(valueComparerFromCollection);
}
[Test]
public void GetOverrideByTypeWhenAllComparersHaveFilters()
{
var valueComparer1 = Substitute.For<IValueComparer>();
var valueComparer2 = Substitute.For<IValueComparer>();
var collection = new ComparerOverridesCollection();
collection.AddComparer(typeof(string), valueComparer1, mi => true);
collection.AddComparer(typeof(string), valueComparer2, mi => true);
var valueComparerFromCollection = collection.GetComparer(typeof(string));
Assert.IsNull(valueComparerFromCollection);
}
[TestCase(null)]
[TestCase("")]
[TestCase(" ")]
public void AddComparerByNameWhenNameEmpty(string memberName)
{
var valueComparer = Substitute.For<IValueComparer>();
var collection = new ComparerOverridesCollection();
Assert.Throws<ArgumentException>(() => collection.AddComparer(memberName, valueComparer));
}
[Test]
public void AddComparerByNameWhenComparerNull()
{
var collection = new ComparerOverridesCollection();
Assert.Throws<ArgumentNullException>(() => collection.AddComparer("Name", null));
}
[Test]
public void GetOverrideByNameComparerByMemberInfo()
{
var valueComparer = Substitute.For<IValueComparer>();
var collection = new ComparerOverridesCollection();
var memberInfo = Substitute.ForPartsOf<PropertyInfo>();
memberInfo.PropertyType.Returns(typeof(string));
memberInfo.Name.Returns("Prop1");
collection.AddComparer("Prop1", valueComparer);
var valueComparerFromCollection = collection.GetComparer(memberInfo);
Assert.AreEqual(valueComparer, valueComparerFromCollection);
}
[Test]
public void GetOverrideByNameComparerByMemberInfoWhenTwoComparersMatchCriteria()
{
var valueComparer1 = Substitute.For<IValueComparer>();
var valueComparer2 = Substitute.For<IValueComparer>();
var collection = new ComparerOverridesCollection();
var memberInfo = Substitute.ForPartsOf<PropertyInfo>();
memberInfo.PropertyType.Returns(typeof(string));
memberInfo.Name.Returns("Prop1");
collection.AddComparer("Prop1", valueComparer1);
collection.AddComparer("Prop1", valueComparer2, mi => true);
Assert.Throws<AmbiguousComparerOverrideResolutionException>(() => collection.GetComparer(memberInfo));
}
[Test]
public void GetOverrideByNameComparerByMemberInfoWhenNoComparerMatchCriteria()
{
var valueComparer1 = Substitute.For<IValueComparer>();
var valueComparer2 = Substitute.For<IValueComparer>();
var collection = new ComparerOverridesCollection();
var memberInfo = Substitute.ForPartsOf<PropertyInfo>();
memberInfo.PropertyType.Returns(typeof(string));
memberInfo.Name.Returns("Prop1");
collection.AddComparer("Prop1", valueComparer1, mi => false);
collection.AddComparer("Prop1", valueComparer2, mi => false);
var valueComparerFromCollection = collection.GetComparer(memberInfo);
Assert.IsNull(valueComparerFromCollection);
}
[Test]
public void GetOverrideByNameComparerByMemberInfoWhenOneComparerMatchCriteria()
{
var valueComparer1 = Substitute.For<IValueComparer>();
var valueComparer2 = Substitute.For<IValueComparer>();
var collection = new ComparerOverridesCollection();
var memberInfo = Substitute.ForPartsOf<PropertyInfo>();
memberInfo.PropertyType.Returns(typeof(string));
memberInfo.Name.Returns("Prop1");
collection.AddComparer("Prop1", valueComparer1, mi => false);
collection.AddComparer("Prop1", valueComparer2, mi => true);
var valueComparerFromCollection = collection.GetComparer(memberInfo);
Assert.AreEqual(valueComparer2, valueComparerFromCollection);
}
[Test]
public void GetComparerByMemberInfoWhenNull()
{
var collection = new ComparerOverridesCollection();
Assert.Throws<ArgumentNullException>(() => collection.GetComparer((MemberInfo)null));
}
[Test]
public void GetOverrideByNameComparerByMemberName()
{
var valueComparer = Substitute.For<IValueComparer>();
var collection = new ComparerOverridesCollection();
collection.AddComparer("Prop1", valueComparer);
var valueComparerFromCollection = collection.GetComparer("Prop1");
Assert.AreEqual(valueComparer, valueComparerFromCollection);
}
[Test]
public void GetOverrideByNameComparerByMemberNameWhenTwoComparersMatchCriteria()
{
var valueComparer1 = Substitute.For<IValueComparer>();
var valueComparer2 = Substitute.For<IValueComparer>();
var collection = new ComparerOverridesCollection();
collection.AddComparer("Prop1", valueComparer1);
collection.AddComparer("Prop1", valueComparer2);
Assert.Throws<AmbiguousComparerOverrideResolutionException>(() => collection.GetComparer("Prop1"));
}
[Test]
public void GetOverrideByNameComparerByMemberNameWhenNoComparerMatchCriteria()
{
var valueComparer1 = Substitute.For<IValueComparer>();
var valueComparer2 = Substitute.For<IValueComparer>();
var collection = new ComparerOverridesCollection();
collection.AddComparer("Prop1", valueComparer1, mi => false);
collection.AddComparer("Prop1", valueComparer2, mi => false);
var valueComparerFromCollection = collection.GetComparer("Prop1");
Assert.IsNull(valueComparerFromCollection);
}
[Test]
public void GetComparerByMemberNameWhenNull()
{
var collection = new ComparerOverridesCollection();
Assert.Throws<ArgumentNullException>(() => collection.GetComparer((string)null));
}
}
}
================================================
FILE: ObjectsComparer/ObjectsComparer.Tests/ComparerTests.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using NSubstitute;
using NUnit.Framework;
using ObjectsComparer.Tests.TestClasses;
namespace ObjectsComparer.Tests
{
[TestFixture]
public class ComparerTests
{
[Test]
public void PropertyEquality()
{
var a1 = new A {IntProperty = 10, DateTimeProperty = new DateTime(2017, 1, 1), Property3 = 5};
var a2 = new A {IntProperty = 10, DateTimeProperty = new DateTime(2017, 1, 1), Property3 = 8};
var comparer = new Comparer<A>();
var isEqual = comparer.Compare(a1, a2);
Assert.IsTrue(isEqual);
}
[Test]
public void PropertyInequality()
{
var date1 = new DateTime(2017, 1, 1);
var date2 = new DateTime(2017, 1, 2);
var a1 = new A {IntProperty = 10, DateTimeProperty = date1};
var a2 = new A {IntProperty = 8, DateTimeProperty = date2};
var comparer = new Comparer<A>();
var differences = comparer.CalculateDifferences(a1, a2).ToList();
CollectionAssert.IsNotEmpty(differences);
Assert.AreEqual("IntProperty", differences[0].MemberPath);
Assert.AreEqual("10", differences[0].Value1);
Assert.AreEqual("8", differences[0].Value2);
Assert.AreEqual("DateTimeProperty", differences[1].MemberPath);
// ReSharper disable once SpecifyACultureInStringConversionExplicitly
Assert.AreEqual(date1.ToString(), differences[1].Value1);
// ReSharper disable once SpecifyACultureInStringConversionExplicitly
Assert.AreEqual(date2.ToString(), differences[1].Value2);
}
[Test]
public void ReadOnlyPropertyEquality()
{
var a1 = new A(1.99);
var a2 = new A(1.99);
var comparer = new Comparer<A>();
var isEqual = comparer.Compare(a1, a2);
Assert.IsTrue(isEqual);
}
[Test]
public void ReadOnlyPropertyInequality()
{
var a1 = new A(1.99);
var a2 = new A(0.89);
var comparer = new Comparer<A>();
var differences = comparer.CalculateDifferences(a1, a2).ToList();
CollectionAssert.IsNotEmpty(differences);
Assert.AreEqual("ReadOnlyProperty", differences.First().MemberPath);
Assert.AreEqual("1.99", differences.First().Value1);
Assert.AreEqual("0.89", differences.First().Value2);
}
[Test]
public void ProtectedProperty()
{
var a1 = new A(true);
var a2 = new A(false);
var comparer = new Comparer<A>();
var isEqual = comparer.Compare(a1, a2);
Assert.IsTrue(isEqual);
}
[Test]
public void FieldEquality()
{
var a1 = new A {Field = 9};
var a2 = new A {Field = 9};
var comparer = new Comparer<A>();
var isEqual = comparer.Compare(a1, a2);
Assert.IsTrue(isEqual);
}
[Test]
public void FieldInequality()
{
var a1 = new A {Field = 10};
var a2 = new A {Field = 8};
var comparer = new Comparer<A>();
var differences = comparer.CalculateDifferences(a1, a2).ToList();
CollectionAssert.IsNotEmpty(differences);
gitextract_agfyhd9m/ ├── .gitignore ├── LICENSE ├── ObjectsComparer/ │ ├── ObjectsComparer/ │ │ ├── AbstractComparer.cs │ │ ├── AbstractComparer~1.cs │ │ ├── Attributes/ │ │ │ └── IgnoreInComparisonAttribute.cs │ │ ├── BaseComparer.cs │ │ ├── Comparer.cs │ │ ├── ComparerOverridesCollection.cs │ │ ├── ComparersFactory.cs │ │ ├── Comparer~1.cs │ │ ├── ComparisonSettings.cs │ │ ├── CustomComparers/ │ │ │ ├── AbstractDynamicObjectsComprer.cs │ │ │ ├── AbstractEnumerablesComparer.cs │ │ │ ├── CompilerGeneratedObjectComparer.cs │ │ │ ├── DynamicObjectComparer.cs │ │ │ ├── EnumerablesComparer.cs │ │ │ ├── EnumerablesComparer~1.cs │ │ │ ├── ExpandoObjectComparer.cs │ │ │ ├── GenericEnumerablesComparer.cs │ │ │ ├── HashSetsComparer.cs │ │ │ ├── HashSetsComparer~1.cs │ │ │ ├── IComparerWithCondition.cs │ │ │ ├── MultidimensionalArrayComparer~1.cs │ │ │ ├── MultidimensionalArraysComparer.cs │ │ │ └── TypesComparer.cs │ │ ├── Difference.cs │ │ ├── DifferenceTypes.cs │ │ ├── Exceptions/ │ │ │ ├── AmbiguousComparerOverrideResolutionException.cs │ │ │ └── ValueComparerExistsException.cs │ │ ├── IBaseComparer.cs │ │ ├── IComparer.cs │ │ ├── IComparersFactory.cs │ │ ├── IComparer~1.cs │ │ ├── LICENSE │ │ ├── ObjectsComparer.csproj │ │ ├── ObjectsComparer.csproj.DotSettings │ │ ├── Properties/ │ │ │ └── AssemblyInfo.cs │ │ ├── Utils/ │ │ │ ├── MemberInfoExtensions.cs │ │ │ ├── PropertyHelper.cs │ │ │ └── TypeExtensions.cs │ │ └── ValueComparers/ │ │ ├── AbstractValueComparer.cs │ │ ├── AbstractValueComparer~1.cs │ │ ├── DefaultValueComparer.cs │ │ ├── DefaultValueValueComparer.cs │ │ ├── DoNotCompareValueComparer.cs │ │ ├── DynamicValueComparer.cs │ │ ├── IValueComparer.cs │ │ ├── IValueComparer~1.cs │ │ ├── IgnoreCaseStringsValueComparer.cs │ │ ├── NulableStringsValueComparer.cs │ │ ├── ToStringComparer.cs │ │ └── UriComparer.cs │ ├── ObjectsComparer.Examples/ │ │ ├── BasicExamples/ │ │ │ ├── BasicExampleTests.cs │ │ │ └── ClassA.cs │ │ ├── Example1/ │ │ │ ├── Error.cs │ │ │ ├── Example1Tests.cs │ │ │ └── Message.cs │ │ ├── Example2/ │ │ │ ├── Example2Tests.cs │ │ │ ├── MyComparersFactory.cs │ │ │ ├── Person.cs │ │ │ └── PhoneNumberComparer.cs │ │ ├── Example3/ │ │ │ ├── Example3Tests.cs │ │ │ ├── Settings0.json │ │ │ ├── Settings1.json │ │ │ └── Settings2.json │ │ ├── Example4/ │ │ │ ├── CustomFormulaItemsComparer.cs │ │ │ ├── Example4Tests.cs │ │ │ ├── Formula.cs │ │ │ ├── FormulaItem.cs │ │ │ └── MyComparersFactory.cs │ │ ├── Example5/ │ │ │ ├── Error.cs │ │ │ ├── Example5Tests.cs │ │ │ └── IgnoreAttribute.cs │ │ ├── ObjectsComparer.Examples.csproj │ │ └── OutputHelper.cs │ ├── ObjectsComparer.Tests/ │ │ ├── AbstractComparerGenericTests.cs │ │ ├── AbstractComparerTests.cs │ │ ├── ComparerNonGenericTests.cs │ │ ├── ComparerOverridesCollectionTests.cs │ │ ├── ComparerTests.cs │ │ ├── Comparer_CompilerGeneratedObjectsTests.cs │ │ ├── Comparer_DynamicObjectsTests.cs │ │ ├── Comparer_ExpandoObjectsTests.cs │ │ ├── Comparer_GenericEnumerableTests.cs │ │ ├── Comparer_IPEndPointTests.cs │ │ ├── Comparer_Issue24Tests.cs │ │ ├── Comparer_MultidimensionalArraysTests.cs │ │ ├── Comparer_NonGenericEnumerableTests.cs │ │ ├── Comparer_OverridesTests.cs │ │ ├── Comparer_StringBuilderTests.cs │ │ ├── Comparer_UriTests.cs │ │ ├── ComparersFactoryTests.cs │ │ ├── ComparisonSettingsTests.cs │ │ ├── CustomComparers/ │ │ │ ├── AbstractValueComparerTests.cs │ │ │ ├── DynamicValueComparerTests.cs │ │ │ ├── EnumerablesComparerGenericTests.cs │ │ │ ├── EnumerablesComparerTests.cs │ │ │ ├── HashSetsComparerTests.cs │ │ │ └── TypesComparerTests.cs │ │ ├── DifferenceTests.cs │ │ ├── ObjectsComparer.Tests.csproj │ │ ├── ObjectsComparer.Tests.csproj.DotSettings │ │ ├── ParentInterfacePropertiesTests.cs │ │ ├── TestClasses/ │ │ │ ├── A.cs │ │ │ ├── B.cs │ │ │ ├── Child.cs │ │ │ ├── CollectionOfB.cs │ │ │ ├── EnumerableImplementation.cs │ │ │ ├── FlagsEnum.cs │ │ │ ├── ITestInterface.cs │ │ │ ├── InheritedFromB.cs │ │ │ ├── MultidimensionalArrays.cs │ │ │ ├── Parent.cs │ │ │ ├── ParentChild.cs │ │ │ ├── TestEnum.cs │ │ │ ├── TestInterfaceImplementation1.cs │ │ │ ├── TestInterfaceImplementation2.cs │ │ │ └── TestStruct.cs │ │ ├── Utils/ │ │ │ └── TypeExtensionsTests.cs │ │ └── ValueComparers/ │ │ ├── DefaultValueComparerTests.cs │ │ ├── DefaultValueValueComparerTests.cs │ │ ├── DoNotCompareValueComparerTests.cs │ │ ├── IgnoreCaseStringsValueComparerTests.cs │ │ └── NulableStringsValueComparerTests.cs │ └── ObjectsComparer.sln └── README.md
SYMBOL INDEX (645 symbols across 112 files)
FILE: ObjectsComparer/ObjectsComparer.Examples/BasicExamples/BasicExampleTests.cs
class BasicExampleTests (line 13) | [TestFixture]
method BasicEquality (line 17) | [Test]
method BasicInequality (line 31) | [Test]
method BasicInequalityWhenSubclass (line 47) | [Test]
method GenericEnumerablesEquality (line 65) | [Test]
method GenericEnumerablesInequalityWhenDifferentLength (line 79) | [Test]
method GenericEnumerablesInequalityWhenDifferentValue (line 95) | [Test]
method HashSetsEquality (line 113) | [Test]
method HashSetsInequality (line 127) | [Test]
method StringBuilderEquality (line 146) | [Test]
method StringBuilderInequality (line 160) | [Test]
method NonGenericWhenDifferentTypes (line 178) | [Test]
method MultidimensionalArraysInequality (line 198) | [Test]
method MultidimensionalArraysSizeInequality1 (line 216) | [Test]
method MultidimensionalArraysSizeInequality2 (line 235) | [Test]
method IntIntInequality (line 254) | [Test]
method MultidimensionalArraysSizeInequality3 (line 273) | [Test]
method ExpandoObject (line 294) | [Test]
method ExpandoObjectWhenMissedFieldsAndUseDefaults (line 319) | [Test]
class DynamicDictionary (line 343) | private class DynamicDictionary : DynamicObject
method TryGetMember (line 350) | public override bool TryGetMember(GetMemberBinder binder, out object...
method TrySetMember (line 357) | public override bool TrySetMember(SetMemberBinder binder, object value)
method GetDynamicMemberNames (line 364) | public override IEnumerable<string> GetDynamicMemberNames()
method DynamicObject (line 370) | [Test]
method CompilerGeneratedDynamicObjects (line 395) | [Test]
class MyValueComparer (line 424) | public class MyValueComparer : AbstractValueComparer<string>
method Compare (line 426) | public override bool Compare(string obj1, string obj2, ComparisonSet...
method Overrides (line 431) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Examples/BasicExamples/ClassA.cs
class ClassA (line 3) | public class ClassA
class SubClassA (line 12) | public class SubClassA
FILE: ObjectsComparer/ObjectsComparer.Examples/Example1/Error.cs
class Error (line 3) | public class Error
FILE: ObjectsComparer/ObjectsComparer.Examples/Example1/Example1Tests.cs
class Example1Tests (line 10) | [TestFixture]
method SetUp (line 15) | [SetUp]
method EqualMessagesWithoutErrors (line 32) | [Test]
method EqualMessagesWithErrors (line 58) | [Test]
method UnequalMessages (line 94) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Examples/Example1/Message.cs
class Message (line 6) | public class Message
method ToString (line 22) | public override string ToString()
FILE: ObjectsComparer/ObjectsComparer.Examples/Example2/Example2Tests.cs
class Example2Tests (line 9) | [TestFixture]
method SetUp (line 15) | [SetUp]
method EqualPersonsTest (line 22) | [Test]
method DifferentPersonsTest (line 48) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Examples/Example2/MyComparersFactory.cs
class MyComparersFactory (line 5) | public class MyComparersFactory : ComparersFactory
method GetObjectsComparer (line 7) | public override IComparer<T> GetObjectsComparer<T>(ComparisonSettings ...
FILE: ObjectsComparer/ObjectsComparer.Examples/Example2/Person.cs
class Person (line 5) | public class Person
method ToString (line 17) | public override string ToString()
FILE: ObjectsComparer/ObjectsComparer.Examples/Example2/PhoneNumberComparer.cs
class PhoneNumberComparer (line 5) | public class PhoneNumberComparer: AbstractValueComparer<string>
method Compare (line 7) | public override bool Compare(string obj1, string obj2, ComparisonSetti...
method ExtractDigits (line 12) | private string ExtractDigits(string str)
FILE: ObjectsComparer/ObjectsComparer.Examples/Example3/Example3Tests.cs
class Example3Tests (line 14) | [TestFixture]
method SetUp (line 20) | [SetUp]
method Settings1 (line 45) | [Test]
method Settings2 (line 60) | [Test]
method LoadJson (line 84) | private string LoadJson(string fileName)
FILE: ObjectsComparer/ObjectsComparer.Examples/Example4/CustomFormulaItemsComparer.cs
class CustomFormulaItemsComparer (line 6) | public class CustomFormulaItemsComparer: AbstractComparer<IList<FormulaI...
method CustomFormulaItemsComparer (line 8) | public CustomFormulaItemsComparer(ComparisonSettings settings, BaseCom...
method CalculateDifferences (line 12) | public override IEnumerable<Difference> CalculateDifferences(IList<For...
FILE: ObjectsComparer/ObjectsComparer.Examples/Example4/Example4Tests.cs
class Example4Tests (line 9) | [TestFixture]
method SetUp (line 15) | [SetUp]
method List_Of_Equal_Sizes_But_Is_Inequality (line 22) | [Test]
method List_Of_Different_Sizes_But_Is_Inequality (line 68) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Examples/Example4/Formula.cs
class Formula (line 5) | public class Formula
FILE: ObjectsComparer/ObjectsComparer.Examples/Example4/FormulaItem.cs
class FormulaItem (line 3) | public class FormulaItem
FILE: ObjectsComparer/ObjectsComparer.Examples/Example4/MyComparersFactory.cs
class MyComparersFactory (line 5) | public class MyComparersFactory : ComparersFactory
method GetObjectsComparer (line 7) | public override IComparer<T> GetObjectsComparer<T>(ComparisonSettings ...
FILE: ObjectsComparer/ObjectsComparer.Examples/Example5/Error.cs
class Error (line 3) | public class Error
FILE: ObjectsComparer/ObjectsComparer.Examples/Example5/Example5Tests.cs
class Example5Tests (line 5) | [TestFixture]
method IgnoreByAttribute (line 8) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Examples/Example5/IgnoreAttribute.cs
class IgnoreAttribute (line 5) | [AttributeUsage(AttributeTargets.Property)]
FILE: ObjectsComparer/ObjectsComparer.Examples/OutputHelper.cs
class OutputHelper (line 8) | public static class OutputHelper
method ResultToOutput (line 10) | public static void ResultToOutput(bool isEqual, IEnumerable<Difference...
FILE: ObjectsComparer/ObjectsComparer.Tests/AbstractComparerGenericTests.cs
class AbstractComparerGenericTests (line 7) | [TestFixture]
method SetUp (line 14) | [SetUp]
method CalculateDifferences (line 23) | [Test]
method CompareWithOutParameterWhenNotEqual (line 31) | [Test]
method CompareWithOutParameterWhenEqual (line 44) | [Test]
method CompareWithoutOutParameterWhenNotEqual (line 57) | [Test]
method CompareWithoutOutParameterWhenEqual (line 69) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/AbstractComparerTests.cs
class AbstractComparerTests (line 7) | [TestFixture]
method SetUp (line 14) | [SetUp]
method CalculateDifferences (line 23) | [Test]
method CompareWithOutParameterWhenNotEqual (line 31) | [Test]
method CompareWithOutParameterWhenEqual (line 44) | [Test]
method CompareWithoutOutParameterWhenNotEqual (line 57) | [Test]
method CompareWithoutOutParameterWhenEqual (line 69) | [Test]
method NonGenericCompareWithOutParameterWhenNotEqual (line 80) | [Test]
method NonGenericCompareWithOutParameterWhenEqual (line 93) | [Test]
method NonGenericCompareWithoutOutParameterWhenNotEqual (line 106) | [Test]
method NonGenericCompareWithoutOutParameterWhenEqual (line 118) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/ComparerNonGenericTests.cs
class ComparerNonGenericTests (line 8) | [TestFixture]
method PropertyEquality (line 11) | [Test]
method PropertyInequality (line 23) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/ComparerOverridesCollectionTests.cs
class ComparerOverridesCollectionTests (line 9) | [TestFixture]
method AddComparerByMemberInfoWhenMemberNull (line 12) | [Test]
method AddComparerByMemberInfoWhenComparerNull (line 22) | [Test]
method AddComparerByMemberInfoWhenExists (line 31) | [Test]
method GetOverrideByMemberInfoComparer (line 43) | [Test]
method GetComparerByMemberInfoWhenNotExists (line 63) | [Test]
method AddComparerByTypeWhenTypeNull (line 79) | [Test]
method AddComparerByTypeWhenComparerNull (line 88) | [Test]
method GetOverrideByTypeComparerByMemberInfo (line 96) | [Test]
method GetOverrideByTypeComparerByType (line 110) | [Test]
method GetComparerByTypeWhenNull (line 124) | [Test]
method GetOverrideByTypeComparerWhenTwoComparersMatchCriteria (line 132) | [Test]
method GetOverrideByTypeComparerWhenOneComparerMatchCriteria (line 149) | [Test]
method GetOverrideByTypeComparerWhenNoComparerMatchCriteria (line 166) | [Test]
method GetOverrideByTypeWhenOnlyOneComparerDoNotHaveFilter (line 183) | [Test]
method GetOverrideByTypeWhenMoreThanOneComparerMatchCriteria (line 197) | [Test]
method GetOverrideByTypeWhenNoComparerMatchCriteria (line 210) | [Test]
method GetOverrideByTypeWhenAllComparersHaveFilters (line 222) | [Test]
method AddComparerByNameWhenNameEmpty (line 236) | [TestCase(null)]
method AddComparerByNameWhenComparerNull (line 247) | [Test]
method GetOverrideByNameComparerByMemberInfo (line 255) | [Test]
method GetOverrideByNameComparerByMemberInfoWhenTwoComparersMatchCriteria (line 270) | [Test]
method GetOverrideByNameComparerByMemberInfoWhenNoComparerMatchCriteria (line 285) | [Test]
method GetOverrideByNameComparerByMemberInfoWhenOneComparerMatchCriteria (line 302) | [Test]
method GetComparerByMemberInfoWhenNull (line 319) | [Test]
method GetOverrideByNameComparerByMemberName (line 327) | [Test]
method GetOverrideByNameComparerByMemberNameWhenTwoComparersMatchCriteria (line 339) | [Test]
method GetOverrideByNameComparerByMemberNameWhenNoComparerMatchCriteria (line 351) | [Test]
method GetComparerByMemberNameWhenNull (line 365) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/ComparerTests.cs
class ComparerTests (line 10) | [TestFixture]
method PropertyEquality (line 13) | [Test]
method PropertyInequality (line 25) | [Test]
method ReadOnlyPropertyEquality (line 47) | [Test]
method ReadOnlyPropertyInequality (line 59) | [Test]
method ProtectedProperty (line 74) | [Test]
method FieldEquality (line 86) | [Test]
method FieldInequality (line 98) | [Test]
method ReadOnlyFieldEquality (line 113) | [Test]
method ReadOnlyFieldInequality (line 125) | [Test]
method ProtectedField (line 140) | [Test]
method ClassPropertyEquality (line 152) | [Test]
method ClassPropertyInequality (line 164) | [Test]
method ClassPropertyInequalityFirstNull (line 179) | [Test]
method ClassPropertyInequalitySecondNull (line 194) | [Test]
method NoRecursiveComparison (line 209) | [Test]
method InterfacePropertyEquality (line 221) | [Test]
method InterfacePropertyInequality (line 236) | [Test]
method StructPropertyEquality (line 254) | [Test]
method StructPropertyInequality (line 266) | [Test]
method EnumPropertyEquality (line 281) | [Test]
method EnumPropertyInequality (line 293) | [Test]
method SetDefaultComparer (line 308) | [Test]
method SetDefaultComparerNullException (line 324) | [Test]
method InheritedAndBaseClassInequality (line 332) | [Test]
method InheritedAndBaseClassEquality (line 350) | [Test]
method FlagsInequality (line 362) | [TestCase(FlagsEnum.Flag1 | FlagsEnum.Flag2, FlagsEnum.Flag1 | FlagsEn...
method FlagsEquality (line 382) | [TestCase(FlagsEnum.Flag1 | FlagsEnum.Flag2, FlagsEnum.Flag1 | FlagsEn...
method TypePropertyEquality (line 395) | [Test]
method TypePropertyInequality (line 407) | [Test]
method TimeSpanEquality (line 423) | [Test]
method TimeSpanInequality (line 435) | [Test]
method GuidEquality (line 451) | [Test]
method GuidInequality (line 463) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/Comparer_CompilerGeneratedObjectsTests.cs
class ComparerCompilerGeneratedObjectComparerObjectsTests (line 7) | [TestFixture]
method DifferentValues (line 10) | [Test]
method MissedFields (line 37) | [Test]
method MissedFieldsAndUseDefaults (line 63) | [Test]
method Hierarchy (line 89) | [Test]
method DifferentTypes (line 106) | [Test]
method NullsAreEqual (line 132) | [Test]
method NullAndMissedMemberAreNotEqual (line 150) | [Test]
method NullValues (line 174) | [Test]
method ComparerOverrideWhenEqual (line 200) | [Test]
method ComparerOverrideWhenNotEqual (line 222) | [Test]
method ComparerOverrideWhenNullAndValueType (line 249) | [Test]
method UseDefaultValuesWhenSubclassNotSpecified (line 275) | [Test]
method DifferenceWhenSubclassNotSpecified (line 295) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/Comparer_DynamicObjectsTests.cs
class ComparerDynamicObjectsTests (line 9) | [TestFixture]
class DynamicDictionary (line 12) | private class DynamicDictionary : DynamicObject
method TryGetMember (line 19) | public override bool TryGetMember(GetMemberBinder binder, out object...
method TrySetMember (line 26) | public override bool TrySetMember(SetMemberBinder binder, object value)
method GetDynamicMemberNames (line 33) | public override IEnumerable<string> GetDynamicMemberNames()
method DifferentValues (line 40) | [Test]
method MissedFields (line 64) | [Test]
method MissedFieldsAndUseDefaults (line 85) | [Test]
method Hierarchy (line 107) | [Test]
method DifferentTypes (line 128) | [Test]
method NullsAreEqual (line 150) | [Test]
method NullAndMissedMemberAreNotEqual (line 164) | [Test]
method NullValues (line 184) | [Test]
method ComparerOverrideWhenEqual (line 206) | [Test]
method ComparerOverrideWhenNotEqual (line 224) | [Test]
method ComparerOverrideWhenNullAndValueType (line 247) | [Test]
method ComperaNonDynamicProperty (line 269) | [Test]
method UseDefaultValuesWhenSubclassNotSpecified (line 287) | [Test]
method DifferenceWhenSubclassNotSpecified (line 303) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/Comparer_ExpandoObjectsTests.cs
class ComparerExpandoObjectsTests (line 10) | [TestFixture]
method DifferentValues (line 13) | [Test]
method MissedFields (line 37) | [Test]
method MissedFieldsAndUseDefaults (line 58) | [Test]
method Hierarchy (line 80) | [Test]
method DifferentTypes (line 101) | [Test]
method NullsAreEqual (line 123) | [Test]
method NullAndMissedMemberAreNotEqual (line 137) | [Test]
method NullValues (line 157) | [Test]
method ComparerOverrideWhenEqual (line 179) | [Test]
method ComparerOverrideWhenNotEqual (line 197) | [Test]
method ComparerOverrideWhenNullAndValueType (line 220) | [Test]
method UseDefaultValuesWhenSubclassNotSpecified (line 242) | [Test]
method DifferenceWhenSubclassNotSpecified (line 258) | [Test]
method ExpandoObjectWithCollections (line 278) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/Comparer_GenericEnumerableTests.cs
class ComparerGenericEnumerableTests (line 9) | [TestFixture]
method ValueTypeArrayEquality (line 12) | [Test]
method PrimitiveTypeArrayInequalityCount (line 24) | [Test]
method PrimitiveTypeArrayInequalityMember (line 40) | [Test]
method PrimitiveTypeArrayInequalityFirstNull (line 55) | [Test]
method PrimitiveTypeArrayInequalitySecondNull (line 71) | [Test]
method ClassArrayEquality (line 86) | [Test]
method ClassArrayInequalityCount (line 98) | [Test]
method ClassArrayInequalityProperty (line 114) | [Test]
method CollectionEquality (line 129) | [Test]
method CollectionInequalityCount (line 141) | [Test]
method CollectionAndNullInequality (line 158) | [Test]
method NullAndCollectionInequality (line 174) | [Test]
method IgnoreAttributeComparisonEquality (line 190) | [Test]
method IgnoreAttributeComparisonInEquality (line 208) | [Test]
method IgnoreAttributeComparisonDeepEquality (line 231) | [Test]
method IgnoreAttributeComparisonDeepInEquality (line 288) | [Test]
method CollectionInequalityProperty (line 351) | [Test]
method ClassImplementsCollectionEquality (line 366) | [Test]
method ClassImplementsCollectionInequalityCount (line 378) | [Test]
method ClassImplementsCollectionInequalityProperty (line 395) | [Test]
method NullAndEmptyComparisonGenericInequality (line 410) | [Test]
method NullAndEmptyComparisonGenericEquality (line 427) | [Test]
method FlagsInequality (line 440) | [TestCase(FlagsEnum.Flag1 | FlagsEnum.Flag2, FlagsEnum.Flag1 | FlagsEn...
method FlagsEquality (line 460) | [TestCase(FlagsEnum.Flag1 | FlagsEnum.Flag2, FlagsEnum.Flag1 | FlagsEn...
method CollectionOfBCountInequality1 (line 473) | [Test]
method CollectionOfBCountInequality2 (line 498) | [Test]
method HashSetEqualitySameOrder (line 524) | [Test]
method HashSetEqualityDifferentOrder (line 536) | [Test]
method HashSetInequalityDifferentElements (line 548) | [Test]
method HashSetInequalityDifferentNumberOfElements (line 567) | [Test]
method HashSetAndNullInequality (line 584) | [Test]
method IgnoreCapacityForLists (line 600) | [Test]
method CompareAsIList (line 622) | [Test]
method DictionaryEqualitySameOrder (line 638) | [Test]
method DictionaryInequalityDifferentOrder (line 650) | [Test]
method DictionaryInequalityDifferentNumberOfElements (line 662) | [Test]
method DictionaryInequalityDifferentValue (line 675) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/Comparer_IPEndPointTests.cs
class Comparer_IPEndPointTests (line 7) | [TestFixture]
method Equality (line 10) | [Test]
method Inequality (line 22) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/Comparer_Issue24Tests.cs
class Comparer_Issue24Tests (line 10) | [TestFixture]
class MyComparersFactory (line 13) | class MyComparersFactory : ComparersFactory
method GetObjectsComparer (line 15) | public override IComparer<T> GetObjectsComparer<T>(ComparisonSetting...
class TestClassA (line 30) | class TestClassA
class TestClassB (line 35) | class TestClassB
method OverrideString (line 42) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/Comparer_MultidimensionalArraysTests.cs
class ComparerMultidimensionalArraysTests (line 7) | [TestFixture]
method IntOfIntInequality1 (line 10) | [Test]
method IntOfIntInequality2 (line 28) | [Test]
method IntOfIntInequality3 (line 49) | [Test]
method IntOfIntInequality4 (line 67) | [Test]
method IntOfIntInequality5 (line 85) | [Test]
method IntOfIntInequality6 (line 103) | [Test]
method IntOfIntInequality7 (line 121) | [Test]
method IntOfIntEquality1 (line 139) | [Test]
method IntOfIntEquality2 (line 151) | [Test]
method IntOfIntEquality3 (line 163) | [Test]
method IntOfIntEquality4 (line 175) | [Test]
method IntOfIntEquality5 (line 187) | [Test]
method IntIntInequality1 (line 199) | [Test]
method IntIntInequality2 (line 217) | [Test]
method IntIntInequality3 (line 235) | [Test]
method IntIntInequality4 (line 253) | [Test]
method IntIntInequality5 (line 271) | [Test]
method IntIntInequality6 (line 289) | [Test]
method IntIntInequality7 (line 307) | [Test]
method IntIntEquality1 (line 325) | [Test]
method IntIntEquality2 (line 337) | [Test]
method IntIntEquality3 (line 349) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/Comparer_NonGenericEnumerableTests.cs
class ComparerNonGenericEnumerableTests (line 8) | [TestFixture]
method Equality (line 11) | [Test]
method InequalityCount (line 23) | [Test]
method InequalityProperty (line 39) | [Test]
method NullElementsEquality (line 54) | [Test]
method NullAndNotNullElementsInequality (line 66) | [Test]
method InequalityType (line 84) | [Test]
method DerivedClassEquality (line 99) | [Test]
method DerivedClassInequalityProperty (line 111) | [Test]
method NullAndEmptyInequality (line 126) | [Test]
method NullAndEmptyEquality (line 141) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/Comparer_OverridesTests.cs
class ComparerOverridesTests (line 9) | [TestFixture]
method OverrideStringComparisonWhenEqual (line 12) | [Test]
method OverrideStringComparisonWhenNotEqual (line 28) | [Test]
method OverrideIntComparisonWhenNotEqual (line 49) | [Test]
method OverrideIntComparisonWhenEqual (line 69) | [Test]
method OverridePropertyComparisonWhenEqual (line 86) | [Test]
method OverrideBClassComparerWhenEqual (line 102) | [Test]
method OverrideBClassComparerWhenNotEqual (line 116) | [Test]
method OverrideBClassProperty1ComparerWhenEqual (line 133) | [Test]
method OverrideBClassProperty1ComparerWhenNotEqual (line 147) | [Test]
method OverrideBClassProperty1ComparerWithFunction (line 164) | [Test]
method OverrideBClassProperty1ComparerWithFunctionAndDefaultToString (line 180) | [Test]
method OverrideBClassProperty1ByMemberInfo (line 198) | [Test]
method OverrideByName (line 216) | [Test]
method OverrideMemberHighestPriority (line 233) | [Test]
method OverrideMemberHigherPriorityThanByName (line 258) | [Test]
method OverrideTypeWithFilterAndByName (line 280) | [Test]
method IgnoreByName (line 301) | [Test]
method IgnoreByType (line 315) | [Test]
method IgnoreByMember (line 329) | [Test]
method OverrideByMemberFilter (line 343) | [Test]
method IgnoreByMemberFilter (line 359) | [Test]
method CreateClassBComparerAsPhone (line 372) | private IValueComparer CreateClassBComparerAsPhone()
method CreatePhoneComparer (line 387) | private IValueComparer CreatePhoneComparer()
method ExtractDigits (line 402) | private string ExtractDigits(string str)
FILE: ObjectsComparer/ObjectsComparer.Tests/Comparer_StringBuilderTests.cs
class Comparer_StringBuilderTests (line 7) | [TestFixture]
method StringBuilderEquality (line 10) | [Test]
method StringBuilderInequality (line 22) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/Comparer_UriTests.cs
class Comparer_UriTests (line 8) | [TestFixture]
class TestClass (line 11) | public class TestClass
method Equality (line 16) | [Test]
method Inequality (line 28) | [Test]
method ListOfUris (line 44) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/ComparersFactoryTests.cs
class ComparersFactoryTests (line 8) | [TestFixture]
class CustomFactory (line 13) | private class CustomFactory : ComparersFactory
method CustomFactory (line 17) | public CustomFactory(IComparer<B> comparerB)
method GetObjectsComparer (line 22) | public override IComparer<T> GetObjectsComparer<T>(ComparisonSetting...
method SetUp (line 33) | [SetUp]
method GetObjectsComparerGeneric (line 39) | [Test]
method GetObjectsComparer (line 50) | [Test]
method CustomFactoryGenericMethod (line 61) | [Test]
method CustomFactoryNongenericMethod (line 71) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/ComparisonSettingsTests.cs
class ComparisonSettingsTests (line 6) | [TestFixture]
method SetgetCustomSettingWithoutKey (line 9) | [Test]
method SetgetCustomSettingWithKey (line 20) | [Test]
method WronkKey (line 34) | [Test]
method WronkType (line 43) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/CustomComparers/AbstractValueComparerTests.cs
class AbstractValueComparerTests (line 6) | [TestFixture]
method DefaultToString (line 9) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/CustomComparers/DynamicValueComparerTests.cs
class DynamicValueComparerTests (line 6) | [TestFixture]
method ConstructorNullCompareFunc (line 9) | [Test]
method ConstructorNullToStringFunc (line 16) | [Test]
method CompareWrongFirstArgument (line 23) | [Test]
method CompareWrongSecondArgument (line 31) | [Test]
method CompareFirstArgumentNullNotValueType (line 39) | [Test]
method CompareFirstArgumentNullValueType (line 49) | [Test]
method CompareSecondArgumentNullNotValueType (line 57) | [Test]
method CompareSecondArgumentNullValueType (line 67) | [Test]
method Compare (line 75) | [TestCase("Str1", "Str2", true)]
method CompareWithDefaultToString (line 89) | [TestCase("Str1", "Str2", true)]
method NulableType (line 103) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/CustomComparers/EnumerablesComparerGenericTests.cs
class EnumerablesComparerGenericTests (line 8) | [TestFixture]
method FirstParameterNotEnumerable (line 11) | [Test]
method SecondParameterNotEnumerable (line 21) | [Test]
method TypeNotIEnumerable (line 31) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/CustomComparers/EnumerablesComparerTests.cs
class EnumerablesComparerTests (line 8) | [TestFixture]
method FirstParameterNotEnumerable (line 11) | [Test]
method SecondParameterNotEnumerable (line 21) | [Test]
method TypeNotIEnumerable (line 31) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/CustomComparers/HashSetsComparerTests.cs
class HashSetsComparerTests (line 8) | [TestFixture]
method FirstParameterNotEnumerable (line 11) | [Test]
method SecondParameterNotEnumerable (line 21) | [Test]
method TypeNotHashSet (line 31) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/CustomComparers/TypesComparerTests.cs
class TypesComparerTests (line 6) | [TestFixture]
method FirstParameterNotType (line 9) | [Test]
method SecondParameterNotEnumerable (line 19) | [Test]
method NullsAreEqual (line 29) | [Test]
method SameTypesAreEqual (line 37) | [Test]
method DifferentTypesAreNotEqual (line 47) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/DifferenceTests.cs
class DifferenceTests (line 5) | [TestFixture]
method DifferenceToString (line 8) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/ParentInterfacePropertiesTests.cs
class ParentInterfacePropertiesTests (line 7) | [TestFixture]
type IParent (line 10) | interface IParent
type IChild (line 15) | interface IChild : IParent
class Child (line 20) | class Child : IChild
method ComparePropertyOfParentInterface (line 26) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/TestClasses/A.cs
class A (line 9) | internal class A
method A (line 70) | public A()
method A (line 75) | public A(double readOnlyProperty)
method A (line 80) | public A(int protectedField)
method A (line 85) | public A(string readOnlyField)
method A (line 90) | public A(bool protectedProperty)
FILE: ObjectsComparer/ObjectsComparer.Tests/TestClasses/B.cs
class B (line 3) | public class B
FILE: ObjectsComparer/ObjectsComparer.Tests/TestClasses/Child.cs
class Child (line 5) | public class Child
method Child (line 9) | public Child(string property1,
FILE: ObjectsComparer/ObjectsComparer.Tests/TestClasses/CollectionOfB.cs
class CollectionOfB (line 9) | internal class CollectionOfB: IProgress<string>, ICollection<B>
method CollectionOfB (line 18) | public CollectionOfB()
method Report (line 23) | public void Report(string value) => Debug.WriteLine(value);
method GetEnumerator (line 25) | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
method GetEnumerator (line 27) | public IEnumerator<B> GetEnumerator() => _collection.GetEnumerator();
method Add (line 29) | public void Add(B item) => _collection.Add(item);
method Clear (line 31) | public void Clear() => _collection.Clear();
method Contains (line 33) | public bool Contains(B item) => _collection.Contains(item);
method CopyTo (line 35) | public void CopyTo(B[] array, int arrayIndex) => _collection.CopyTo(ar...
method Remove (line 37) | public bool Remove(B item) => _collection.Remove(item);
FILE: ObjectsComparer/ObjectsComparer.Tests/TestClasses/EnumerableImplementation.cs
class EnumerableImplementation (line 5) | internal class EnumerableImplementation: IEnumerable
method EnumerableImplementation (line 11) | public EnumerableImplementation(IEnumerable enumerable)
method GetEnumerator (line 16) | public IEnumerator GetEnumerator()
FILE: ObjectsComparer/ObjectsComparer.Tests/TestClasses/FlagsEnum.cs
type FlagsEnum (line 5) | [Flags]
FILE: ObjectsComparer/ObjectsComparer.Tests/TestClasses/ITestInterface.cs
type ITestInterface (line 3) | internal interface ITestInterface
FILE: ObjectsComparer/ObjectsComparer.Tests/TestClasses/InheritedFromB.cs
class InheritedFromB (line 3) | internal class InheritedFromB: B
FILE: ObjectsComparer/ObjectsComparer.Tests/TestClasses/MultidimensionalArrays.cs
class MultidimensionalArrays (line 3) | public class MultidimensionalArrays
FILE: ObjectsComparer/ObjectsComparer.Tests/TestClasses/Parent.cs
class Parent (line 5) | public class Parent
FILE: ObjectsComparer/ObjectsComparer.Tests/TestClasses/ParentChild.cs
class ParentChild (line 9) | public class ParentChild
method ParentChild (line 13) | public ParentChild(Parent myParent,
method ParentChild (line 22) | public ParentChild(Parent myParent,
FILE: ObjectsComparer/ObjectsComparer.Tests/TestClasses/TestEnum.cs
type TestEnum (line 3) | internal enum TestEnum
FILE: ObjectsComparer/ObjectsComparer.Tests/TestClasses/TestInterfaceImplementation1.cs
class TestInterfaceImplementation1 (line 3) | internal class TestInterfaceImplementation1: ITestInterface
FILE: ObjectsComparer/ObjectsComparer.Tests/TestClasses/TestInterfaceImplementation2.cs
class TestInterfaceImplementation2 (line 3) | internal class TestInterfaceImplementation2: ITestInterface
FILE: ObjectsComparer/ObjectsComparer.Tests/TestClasses/TestStruct.cs
type TestStruct (line 3) | internal struct TestStruct
FILE: ObjectsComparer/ObjectsComparer.Tests/Utils/TypeExtensionsTests.cs
class TypeExtensionsTests (line 8) | [TestFixture]
method InheritsFromFirstTypeNull (line 11) | [Test]
method InheritsFromSecondTypeNull (line 19) | [Test]
method InheritsFromEqualTypes (line 27) | [Test]
method InheritsFromEqualGenericTypes (line 35) | [Test]
method InheritsFromEqualGenericTypeAndGenericDefinition (line 43) | [Test]
method InheritsFromEqualGenericTypeAndGenericInterface (line 51) | [Test]
method InheritsFromEqualTypeAndBaseType (line 59) | [Test]
FILE: ObjectsComparer/ObjectsComparer.Tests/ValueComparers/DefaultValueComparerTests.cs
class DefaultValueComparerTests (line 5) | [TestFixture]
method Compare (line 8) | [TestCase(null, null, true)]
method Compare (line 25) | [TestCase(null, "")]
FILE: ObjectsComparer/ObjectsComparer.Tests/ValueComparers/DefaultValueValueComparerTests.cs
class DefaultValueValueComparerTests (line 5) | [TestFixture]
method ValueType (line 8) | [TestCase(0, 5, true)]
method ReferenceType (line 32) | [TestCase(null, "none", true)]
FILE: ObjectsComparer/ObjectsComparer.Tests/ValueComparers/DoNotCompareValueComparerTests.cs
class DoNotCompareValueComparerTests (line 5) | [TestFixture]
method Instance (line 8) | [Test]
method Compare (line 14) | [Test]
method ToString (line 22) | [TestCase(25)]
FILE: ObjectsComparer/ObjectsComparer.Tests/ValueComparers/IgnoreCaseStringsValueComparerTests.cs
class IgnoreCaseStringsValueComparerTests (line 5) | [TestFixture]
method Compare (line 8) | [TestCase(null, null, true)]
FILE: ObjectsComparer/ObjectsComparer.Tests/ValueComparers/NulableStringsValueComparerTests.cs
class NulableStringsValueComparerTests (line 5) | [TestFixture]
method Compare (line 8) | [TestCase(null, null, true)]
method ToString (line 25) | [TestCase(null, "")]
FILE: ObjectsComparer/ObjectsComparer/AbstractComparer.cs
class AbstractComparer (line 10) | public abstract class AbstractComparer: BaseComparer, IComparer
method AbstractComparer (line 12) | protected AbstractComparer(ComparisonSettings settings, BaseComparer p...
method CalculateDifferences (line 17) | public abstract IEnumerable<Difference> CalculateDifferences(Type type...
method CalculateDifferences (line 26) | public IEnumerable<Difference> CalculateDifferences<T>(T obj1, T obj2)
method Compare (line 39) | public bool Compare(Type type, object obj1, object obj2, out IEnumerab...
method Compare (line 53) | public bool Compare(Type type, object obj1, object obj2)
method Compare (line 66) | public bool Compare<T>(T obj1, T obj2, out IEnumerable<Difference> dif...
method Compare (line 78) | public bool Compare<T>(T obj1, T obj2)
FILE: ObjectsComparer/ObjectsComparer/AbstractComparer~1.cs
class AbstractComparer (line 9) | public abstract class AbstractComparer<T>: BaseComparer, IComparer<T>
method AbstractComparer (line 11) | protected AbstractComparer(ComparisonSettings settings, BaseComparer p...
method Compare (line 23) | public bool Compare(T obj1, T obj2, out IEnumerable<Difference> differ...
method Compare (line 36) | public bool Compare(T obj1, T obj2)
method CalculateDifferences (line 47) | public abstract IEnumerable<Difference> CalculateDifferences(T obj1, T...
FILE: ObjectsComparer/ObjectsComparer/Attributes/IgnoreInComparisonAttribute.cs
class IgnoreInComparisonAttribute (line 14) | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
FILE: ObjectsComparer/ObjectsComparer/BaseComparer.cs
class BaseComparer (line 11) | public abstract class BaseComparer: IBaseComparer
method BaseComparer (line 27) | protected BaseComparer(ComparisonSettings settings, BaseComparer paren...
method AddComparerOverride (line 46) | public void AddComparerOverride(Type type, IValueComparer valueCompare...
method AddComparerOverride (line 56) | public void AddComparerOverride(IValueComparer valueComparer, Func<Mem...
method AddComparerOverride (line 67) | public void AddComparerOverride<TType>(IValueComparer valueComparer, F...
method AddComparerOverride (line 78) | public void AddComparerOverride<TProp>(Expression<Func<TProp>> memberL...
method AddComparerOverride (line 90) | public void AddComparerOverride<TProp>(
method AddComparerOverride (line 108) | public void AddComparerOverride<TProp>(
method AddComparerOverride (line 124) | public void AddComparerOverride(MemberInfo memberInfo, IValueComparer ...
method AddComparerOverride (line 135) | public void AddComparerOverride(string memberName, IValueComparer valu...
method SetDefaultComparer (line 144) | public void SetDefaultComparer(IValueComparer valueComparer)
method IgnoreMember (line 153) | public void IgnoreMember<TType>()
method IgnoreMember (line 162) | public void IgnoreMember<TProp>(Expression<Func<TProp>> memberLambda)
method IgnoreMember (line 173) | public void IgnoreMember(string memberName)
method IgnoreMember (line 182) | public void IgnoreMember(Func<MemberInfo, bool> filter)
FILE: ObjectsComparer/ObjectsComparer/Comparer.cs
class Comparer (line 12) | public class Comparer : AbstractComparer
method Comparer (line 26) | public Comparer(ComparisonSettings settings = null, BaseComparer paren...
method CalculateDifferences (line 37) | public override IEnumerable<Difference> CalculateDifferences(Type type...
FILE: ObjectsComparer/ObjectsComparer/ComparerOverridesCollection.cs
class ComparerOverridesCollection (line 10) | internal class ComparerOverridesCollection
class ValueComparerWithFilter (line 12) | private class ValueComparerWithFilter
method ValueComparerWithFilter (line 18) | public ValueComparerWithFilter(IValueComparer valueComparer, Func<Me...
method AddComparer (line 30) | public void AddComparer(MemberInfo memberInfo, IValueComparer valueCom...
method AddComparer (line 45) | public void AddComparer(IValueComparer valueComparer, Func<MemberInfo,...
method AddComparer (line 55) | public void AddComparer(Type type, IValueComparer valueComparer,
method AddComparer (line 79) | public void AddComparer(string memberName, IValueComparer valueComparer,
method Merge (line 100) | public void Merge(ComparerOverridesCollection collection)
method GetComparer (line 129) | public IValueComparer GetComparer(Type type)
method GetComparer (line 150) | public IValueComparer GetComparer(MemberInfo memberInfo)
method GetComparer (line 201) | public IValueComparer GetComparer(string memberName)
FILE: ObjectsComparer/ObjectsComparer/ComparersFactory.cs
class ComparersFactory (line 8) | public class ComparersFactory : IComparersFactory
method GetObjectsComparer (line 17) | public virtual IComparer<T> GetObjectsComparer<T>(ComparisonSettings s...
method GetObjectsComparer (line 29) | public IComparer GetObjectsComparer(Type type, ComparisonSettings sett...
FILE: ObjectsComparer/ObjectsComparer/Comparer~1.cs
class Comparer (line 14) | public class Comparer<T> : AbstractComparer<T>
method Comparer (line 25) | public Comparer(ComparisonSettings settings = null, BaseComparer paren...
method CalculateDifferences (line 57) | public override IEnumerable<Difference> CalculateDifferences(T obj1, T...
method CalculateDifferences (line 62) | internal IEnumerable<Difference> CalculateDifferences(T obj1, T obj2, ...
method GetProperties (line 157) | private List<PropertyInfo> GetProperties(Type type, List<Type> process...
FILE: ObjectsComparer/ObjectsComparer/ComparisonSettings.cs
class ComparisonSettings (line 9) | public class ComparisonSettings
method ComparisonSettings (line 33) | public ComparisonSettings()
method SetCustomSetting (line 46) | public void SetCustomSetting<T>(T value, string key = null)
method GetCustomSetting (line 58) | public T GetCustomSetting<T>(string key = null)
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/AbstractDynamicObjectsComprer.cs
class AbstractDynamicObjectsComprer (line 9) | internal abstract class AbstractDynamicObjectsComprer<T>: AbstractCompar...
method AbstractDynamicObjectsComprer (line 11) | protected AbstractDynamicObjectsComprer(ComparisonSettings settings, B...
method CalculateDifferences (line 15) | public override IEnumerable<Difference> CalculateDifferences(Type type...
method IsMatch (line 115) | public abstract bool IsMatch(Type type, object obj1, object obj2);
method IsStopComparison (line 117) | public abstract bool IsStopComparison(Type type, object obj1, object o...
method SkipMember (line 119) | public abstract bool SkipMember(Type type, MemberInfo member);
method GetProperties (line 121) | protected abstract IList<string> GetProperties(T obj);
method TryGetMemberValue (line 123) | protected abstract bool TryGetMemberValue(T obj, string propertyName, ...
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/AbstractEnumerablesComparer.cs
class AbstractEnumerablesComparer (line 8) | internal abstract class AbstractEnumerablesComparer: AbstractComparer, I...
method AbstractEnumerablesComparer (line 10) | protected AbstractEnumerablesComparer(ComparisonSettings settings, Bas...
method IsStopComparison (line 16) | public bool IsStopComparison(Type type, object obj1, object obj2)
method SkipMember (line 21) | public virtual bool SkipMember(Type type, MemberInfo member)
method CalculateDifferences (line 42) | public abstract override IEnumerable<Difference> CalculateDifferences(...
method IsMatch (line 44) | public abstract bool IsMatch(Type type, object obj1, object obj2);
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/CompilerGeneratedObjectComparer.cs
class CompilerGeneratedObjectComparer (line 9) | internal class CompilerGeneratedObjectComparer : AbstractDynamicObjectsC...
method CompilerGeneratedObjectComparer (line 11) | public CompilerGeneratedObjectComparer(ComparisonSettings settings, Ba...
method IsMatch (line 16) | public override bool IsMatch(Type type, object obj1, object obj2)
method IsStopComparison (line 23) | public override bool IsStopComparison(Type type, object obj1, object o...
method SkipMember (line 28) | public override bool SkipMember(Type type, MemberInfo member)
method GetProperties (line 33) | protected override IList<string> GetProperties(object obj)
method TryGetMemberValue (line 42) | protected override bool TryGetMemberValue(object obj, string propertyN...
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/DynamicObjectComparer.cs
class DynamicObjectComparer (line 10) | internal class DynamicObjectComparer : AbstractDynamicObjectsComprer<Dyn...
class FakeGetMemberBinder (line 12) | private class FakeGetMemberBinder : GetMemberBinder
method FakeGetMemberBinder (line 14) | public FakeGetMemberBinder(string name, bool ignoreCase) : base(name...
method FallbackGetMember (line 18) | public override DynamicMetaObject FallbackGetMember(DynamicMetaObjec...
method DynamicObjectComparer (line 24) | public DynamicObjectComparer(ComparisonSettings settings, BaseComparer...
method IsMatch (line 29) | public override bool IsMatch(Type type, object obj1, object obj2)
method IsStopComparison (line 35) | public override bool IsStopComparison(Type type, object obj1, object o...
method SkipMember (line 40) | public override bool SkipMember(Type type, MemberInfo member)
method GetProperties (line 45) | protected override IList<string> GetProperties(DynamicObject obj)
method TryGetMemberValue (line 50) | protected override bool TryGetMemberValue(DynamicObject obj, string pr...
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/EnumerablesComparer.cs
class EnumerablesComparer (line 10) | internal class EnumerablesComparer : AbstractComparer, IComparerWithCond...
method EnumerablesComparer (line 12) | public EnumerablesComparer(ComparisonSettings settings, BaseComparer p...
method CalculateDifferences (line 17) | public override IEnumerable<Difference> CalculateDifferences(Type type...
method IsMatch (line 91) | public bool IsMatch(Type type, object obj1, object obj2)
method IsStopComparison (line 96) | public bool IsStopComparison(Type type, object obj1, object obj2)
method SkipMember (line 101) | public bool SkipMember(Type type, MemberInfo member)
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/EnumerablesComparer~1.cs
class EnumerablesComparer (line 9) | internal class EnumerablesComparer<T> : AbstractComparer
method EnumerablesComparer (line 13) | public EnumerablesComparer(ComparisonSettings settings, BaseComparer p...
method CalculateDifferences (line 19) | public override IEnumerable<Difference> CalculateDifferences(Type type...
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/ExpandoObjectComparer.cs
class ExpandoObjectComparer (line 10) | internal class ExpandoObjectComparer : AbstractDynamicObjectsComprer<Exp...
method ExpandoObjectComparer (line 12) | public ExpandoObjectComparer(ComparisonSettings settings, BaseComparer...
method IsMatch (line 17) | public override bool IsMatch(Type type, object obj1, object obj2)
method IsStopComparison (line 23) | public override bool IsStopComparison(Type type, object obj1, object o...
method SkipMember (line 28) | public override bool SkipMember(Type type, MemberInfo member) => false;
method GetProperties (line 30) | protected override IList<string> GetProperties(ExpandoObject obj)
method TryGetMemberValue (line 35) | protected override bool TryGetMemberValue(ExpandoObject obj, string pr...
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/GenericEnumerablesComparer.cs
class GenericEnumerablesComparer (line 10) | internal class GenericEnumerablesComparer : AbstractEnumerablesComparer
method GenericEnumerablesComparer (line 12) | public GenericEnumerablesComparer(ComparisonSettings settings, BaseCom...
method CalculateDifferences (line 18) | public override IEnumerable<Difference> CalculateDifferences(Type type...
method IsMatch (line 53) | public override bool IsMatch(Type type, object obj1, object obj2)
method SkipMember (line 58) | public override bool SkipMember(Type type, MemberInfo member)
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/HashSetsComparer.cs
class HashSetsComparer (line 9) | internal class HashSetsComparer : AbstractEnumerablesComparer
method HashSetsComparer (line 11) | public HashSetsComparer(ComparisonSettings settings, BaseComparer pare...
method CalculateDifferences (line 16) | public override IEnumerable<Difference> CalculateDifferences(Type type...
method IsMatch (line 42) | public override bool IsMatch(Type type, object obj1, object obj2)
method SkipMember (line 47) | public override bool SkipMember(Type type, MemberInfo member)
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/HashSetsComparer~1.cs
class HashSetsComparer (line 8) | internal class HashSetsComparer<T> : AbstractComparer
method HashSetsComparer (line 10) | public HashSetsComparer(ComparisonSettings settings, BaseComparer pare...
method CalculateDifferences (line 15) | public override IEnumerable<Difference> CalculateDifferences(Type type...
method IsMatch (line 64) | public bool IsMatch(Type type, object obj1, object obj2)
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/IComparerWithCondition.cs
type IComparerWithCondition (line 6) | internal interface IComparerWithCondition: IComparer
method IsMatch (line 8) | bool IsMatch(Type type, object obj1, object obj2);
method IsStopComparison (line 10) | bool IsStopComparison(Type type, object obj1, object obj2);
method SkipMember (line 12) | bool SkipMember(Type type, MemberInfo member);
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/MultidimensionalArrayComparer~1.cs
class MultidimensionalArrayComparer (line 8) | internal class MultidimensionalArrayComparer<T> : AbstractComparer
method MultidimensionalArrayComparer (line 12) | public MultidimensionalArrayComparer(ComparisonSettings settings, Base...
method CalculateDifferences (line 18) | public override IEnumerable<Difference> CalculateDifferences(Type type...
method IndexToCoordinates (line 80) | private static int[] IndexToCoordinates(Array arr, int i)
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/MultidimensionalArraysComparer.cs
class MultidimensionalArraysComparer (line 8) | internal class MultidimensionalArraysComparer : AbstractEnumerablesComparer
method MultidimensionalArraysComparer (line 10) | public MultidimensionalArraysComparer(ComparisonSettings settings, Bas...
method CalculateDifferences (line 16) | public override IEnumerable<Difference> CalculateDifferences(Type type...
method IsMatch (line 33) | public override bool IsMatch(Type type, object obj1, object obj2)
method SkipMember (line 38) | public override bool SkipMember(Type type, MemberInfo member)
FILE: ObjectsComparer/ObjectsComparer/CustomComparers/TypesComparer.cs
class TypesComparer (line 8) | internal class TypesComparer : AbstractComparer, IComparerWithCondition
method TypesComparer (line 10) | public TypesComparer(ComparisonSettings settings, BaseComparer parentC...
method CalculateDifferences (line 16) | public override IEnumerable<Difference> CalculateDifferences(Type type...
method IsMatch (line 42) | public bool IsMatch(Type type, object obj1, object obj2)
method IsStopComparison (line 47) | public bool IsStopComparison(Type type, object obj1, object obj2) => t...
method SkipMember (line 49) | public bool SkipMember(Type type, MemberInfo member) => true;
FILE: ObjectsComparer/ObjectsComparer/Difference.cs
class Difference (line 6) | public class Difference
method Difference (line 35) | public Difference(string memberPath, string value1, string value2,
method InsertPath (line 49) | public Difference InsertPath(string path)
method ToString (line 64) | public override string ToString()
FILE: ObjectsComparer/ObjectsComparer/DifferenceTypes.cs
type DifferenceTypes (line 8) | public enum DifferenceTypes
FILE: ObjectsComparer/ObjectsComparer/Exceptions/AmbiguousComparerOverrideResolutionException.cs
class AmbiguousComparerOverrideResolutionException (line 9) | public class AmbiguousComparerOverrideResolutionException: Exception
method AmbiguousComparerOverrideResolutionException (line 26) | internal AmbiguousComparerOverrideResolutionException(MemberInfo membe...
method AmbiguousComparerOverrideResolutionException (line 33) | internal AmbiguousComparerOverrideResolutionException(string memberName)
method AmbiguousComparerOverrideResolutionException (line 39) | internal AmbiguousComparerOverrideResolutionException(Type type)
FILE: ObjectsComparer/ObjectsComparer/Exceptions/ValueComparerExistsException.cs
class ValueComparerExistsException (line 9) | public class ValueComparerExistsException: Exception
method ValueComparerExistsException (line 16) | internal ValueComparerExistsException(MemberInfo memberInfo)
FILE: ObjectsComparer/ObjectsComparer/IBaseComparer.cs
type IBaseComparer (line 10) | public interface IBaseComparer
method SetDefaultComparer (line 26) | void SetDefaultComparer(IValueComparer valueComparer);
method AddComparerOverride (line 34) | void AddComparerOverride<TProp>(Expression<Func<TProp>> memberLambda, ...
method AddComparerOverride (line 41) | void AddComparerOverride(MemberInfo memberInfo, IValueComparer valueCo...
method AddComparerOverride (line 49) | void AddComparerOverride(Type type, IValueComparer valueComparer, Func...
method AddComparerOverride (line 57) | void AddComparerOverride<TType>(IValueComparer valueComparer, Func<Mem...
method AddComparerOverride (line 66) | void AddComparerOverride<TProp>(
method AddComparerOverride (line 77) | void AddComparerOverride<TProp>(
method AddComparerOverride (line 87) | void AddComparerOverride(string memberName, IValueComparer valueCompar...
FILE: ObjectsComparer/ObjectsComparer/IComparer.cs
type IComparer (line 9) | public interface IComparer : IBaseComparer
method Compare (line 19) | bool Compare(Type type, object obj1, object obj2, out IEnumerable<Diff...
method Compare (line 29) | bool Compare<T>(T obj1, T obj2, out IEnumerable<Difference> differences);
method Compare (line 38) | bool Compare(Type type, object obj1, object obj2);
method Compare (line 47) | bool Compare<T>(T obj1, T obj2);
method CalculateDifferences (line 56) | IEnumerable<Difference> CalculateDifferences(Type type, object obj1, o...
method CalculateDifferences (line 65) | IEnumerable<Difference> CalculateDifferences<T>(T obj1, T obj2);
FILE: ObjectsComparer/ObjectsComparer/IComparersFactory.cs
type IComparersFactory (line 8) | public interface IComparersFactory
method GetObjectsComparer (line 17) | IComparer<T> GetObjectsComparer<T>(ComparisonSettings settings = null,...
method GetObjectsComparer (line 26) | IComparer GetObjectsComparer(Type type, ComparisonSettings settings = ...
FILE: ObjectsComparer/ObjectsComparer/IComparer~1.cs
type IComparer (line 8) | public interface IComparer<in T>: IBaseComparer
method Compare (line 17) | bool Compare(T obj1, T obj2, out IEnumerable<Difference> differences);
method Compare (line 25) | bool Compare(T obj1, T obj2);
method CalculateDifferences (line 33) | IEnumerable<Difference> CalculateDifferences(T obj1, T obj2);
FILE: ObjectsComparer/ObjectsComparer/Utils/MemberInfoExtensions.cs
class MemberInfoExtensions (line 7) | internal static class MemberInfoExtensions
method GetMemberType (line 9) | public static Type GetMemberType(this MemberInfo memberInfo)
method GetMemberValue (line 26) | public static object GetMemberValue(this MemberInfo memberInfo, object...
method GetMethodName (line 50) | public static string GetMethodName<T>(Expression<Action<T>> expression)
FILE: ObjectsComparer/ObjectsComparer/Utils/PropertyHelper.cs
class PropertyHelper (line 7) | internal class PropertyHelper
method GetMemberInfo (line 9) | public static MemberInfo GetMemberInfo<T>(Expression<Func<T>> memberLa...
FILE: ObjectsComparer/ObjectsComparer/Utils/TypeExtensions.cs
class TypeExtensions (line 7) | internal static class TypeExtensions
method InheritsFrom (line 9) | public static bool InheritsFrom(this Type t1, Type t2)
method IsComparable (line 35) | public static bool IsComparable(this Type type)
method GetDefaultValue (line 43) | public static object GetDefaultValue(this Type t)
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/AbstractValueComparer.cs
class AbstractValueComparer (line 6) | public abstract class AbstractValueComparer: IValueComparer
method Compare (line 8) | public abstract bool Compare(object obj1, object obj2, ComparisonSetti...
method ToString (line 10) | public virtual string ToString(object value)
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/AbstractValueComparer~1.cs
class AbstractValueComparer (line 8) | public abstract class AbstractValueComparer<T>: AbstractValueComparer, I...
method Compare (line 17) | public abstract bool Compare(T obj1, T obj2, ComparisonSettings settin...
method ToString (line 24) | public virtual string ToString(T value)
method Compare (line 36) | public override bool Compare(object obj1, object obj2, ComparisonSetti...
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/DefaultValueComparer.cs
class DefaultValueComparer (line 6) | public class DefaultValueComparer: IValueComparer
method Compare (line 42) | public bool Compare(object obj1, object obj2, ComparisonSettings setti...
method ToString (line 57) | public string ToString(object value)
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/DefaultValueValueComparer.cs
class DefaultValueValueComparer (line 7) | public class DefaultValueValueComparer<T> : IValueComparer
method DefaultValueValueComparer (line 18) | public DefaultValueValueComparer(T defaultValue, IValueComparer valueC...
method Compare (line 32) | public bool Compare(object obj1, object obj2, ComparisonSettings setti...
method ToString (line 45) | public string ToString(object value)
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/DoNotCompareValueComparer.cs
class DoNotCompareValueComparer (line 6) | public class DoNotCompareValueComparer : IValueComparer
method DoNotCompareValueComparer (line 35) | private DoNotCompareValueComparer() { }
method Compare (line 44) | public bool Compare(object obj1, object obj2, ComparisonSettings setti...
method ToString (line 54) | public string ToString(object value)
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/DynamicValueComparer.cs
class DynamicValueComparer (line 10) | public class DynamicValueComparer<T>: IValueComparer
method DynamicValueComparer (line 19) | public DynamicValueComparer(Func<T, T, ComparisonSettings, bool> compa...
method DynamicValueComparer (line 29) | public DynamicValueComparer(Func<T, T, ComparisonSettings, bool> compa...
method Compare (line 42) | public bool Compare(object obj1, object obj2, ComparisonSettings setti...
method ToString (line 55) | public string ToString(object value)
method IsArgumentException (line 63) | private void IsArgumentException(object obj, string argumentName)
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/IValueComparer.cs
type IValueComparer (line 6) | public interface IValueComparer
method Compare (line 15) | bool Compare(object obj1, object obj2, ComparisonSettings settings);
method ToString (line 22) | string ToString(object value);
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/IValueComparer~1.cs
type IValueComparer (line 7) | public interface IValueComparer<in T>: IValueComparer
method Compare (line 16) | bool Compare(T obj1, T obj2, ComparisonSettings settings);
method ToString (line 23) | string ToString(T value);
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/IgnoreCaseStringsValueComparer.cs
class IgnoreCaseStringsValueComparer (line 8) | public class IgnoreCaseStringsValueComparer : AbstractValueComparer<string>
method Compare (line 44) | public override bool Compare(string obj1, string obj2, ComparisonSetti...
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/NulableStringsValueComparer.cs
class NulableStringsValueComparer (line 6) | public class NulableStringsValueComparer: AbstractValueComparer<string>
method Compare (line 42) | public override bool Compare(string obj1, string obj2, ComparisonSetti...
method ToString (line 57) | public override string ToString(string value)
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/ToStringComparer.cs
class ToStringComparer (line 3) | public class ToStringComparer<T> : DynamicValueComparer<T>
method ToStringComparer (line 5) | public ToStringComparer() :
FILE: ObjectsComparer/ObjectsComparer/ValueComparers/UriComparer.cs
class UriComparer (line 5) | public class UriComparer: DynamicValueComparer<Uri>
method UriComparer (line 34) | public UriComparer() :
Condensed preview — 126 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (405K chars).
[
{
"path": ".gitignore",
"chars": 4195,
"preview": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User"
},
{
"path": "LICENSE",
"chars": 1077,
"preview": "MIT License\n\nCopyright (c) 2019 Valerii Tereshchenko\n\nPermission is hereby granted, free of charge, to any person obtain"
},
{
"path": "ObjectsComparer/ObjectsComparer/AbstractComparer.cs",
"chars": 3118,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace ObjectsComparer\n{\n /// <summary>\n //"
},
{
"path": "ObjectsComparer/ObjectsComparer/AbstractComparer~1.cs",
"chars": 1754,
"preview": "using System.Collections.Generic;\nusing System.Linq;\n\nnamespace ObjectsComparer\n{\n /// <summary>\n /// Implementati"
},
{
"path": "ObjectsComparer/ObjectsComparer/Attributes/IgnoreInComparisonAttribute.cs",
"chars": 600,
"preview": "// ***********************************************************************\n// Assembly : Objects Comparer\n// Au"
},
{
"path": "ObjectsComparer/ObjectsComparer/BaseComparer.cs",
"chars": 7761,
"preview": "using System;\nusing System.Linq.Expressions;\nusing System.Reflection;\nusing ObjectsComparer.Utils;\n\nnamespace ObjectsCom"
},
{
"path": "ObjectsComparer/ObjectsComparer/Comparer.cs",
"chars": 2299,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing ObjectsComparer.Utils"
},
{
"path": "ObjectsComparer/ObjectsComparer/ComparerOverridesCollection.cs",
"chars": 7854,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing ObjectsComparer.Excep"
},
{
"path": "ObjectsComparer/ObjectsComparer/ComparersFactory.cs",
"chars": 1358,
"preview": "using System;\n\nnamespace ObjectsComparer\n{\n /// <summary>\n /// Implements Comparers Factory.\n /// </summary>\n "
},
{
"path": "ObjectsComparer/ObjectsComparer/Comparer~1.cs",
"chars": 7263,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing System.Text;\nusing Ob"
},
{
"path": "ObjectsComparer/ObjectsComparer/ComparisonSettings.cs",
"chars": 2729,
"preview": "using System;\nusing System.Collections.Generic;\n\nnamespace ObjectsComparer\n{\n /// <summary>\n /// Configuration fo"
},
{
"path": "ObjectsComparer/ObjectsComparer/CustomComparers/AbstractDynamicObjectsComprer.cs",
"chars": 5277,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing ObjectsComparer.Utils"
},
{
"path": "ObjectsComparer/ObjectsComparer/CustomComparers/AbstractEnumerablesComparer.cs",
"chars": 1406,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Reflection;\nusing ObjectsComparer.Utils;\n\nnamespace Objects"
},
{
"path": "ObjectsComparer/ObjectsComparer/CustomComparers/CompilerGeneratedObjectComparer.cs",
"chars": 1968,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing System.Runtime.Compil"
},
{
"path": "ObjectsComparer/ObjectsComparer/CustomComparers/DynamicObjectComparer.cs",
"chars": 2048,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Dynamic;\nusing System.Linq;\nusing System.Reflection;\nusing"
},
{
"path": "ObjectsComparer/ObjectsComparer/CustomComparers/EnumerablesComparer.cs",
"chars": 3942,
"preview": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nu"
},
{
"path": "ObjectsComparer/ObjectsComparer/CustomComparers/EnumerablesComparer~1.cs",
"chars": 2153,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing ObjectsComparer.Utils"
},
{
"path": "ObjectsComparer/ObjectsComparer/CustomComparers/ExpandoObjectComparer.cs",
"chars": 1575,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Dynamic;\nusing System.Linq;\nusing System.Reflection;\nusing"
},
{
"path": "ObjectsComparer/ObjectsComparer/CustomComparers/GenericEnumerablesComparer.cs",
"chars": 2730,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Linq;\nusing System.R"
},
{
"path": "ObjectsComparer/ObjectsComparer/CustomComparers/HashSetsComparer.cs",
"chars": 1970,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Reflection;\nusing ObjectsComparer.Utils"
},
{
"path": "ObjectsComparer/ObjectsComparer/CustomComparers/HashSetsComparer~1.cs",
"chars": 2271,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing ObjectsComparer.Utils;\n\nnamespace ObjectsCompa"
},
{
"path": "ObjectsComparer/ObjectsComparer/CustomComparers/IComparerWithCondition.cs",
"chars": 324,
"preview": "using System;\nusing System.Reflection;\n\nnamespace ObjectsComparer\n{\n internal interface IComparerWithCondition: ICom"
},
{
"path": "ObjectsComparer/ObjectsComparer/CustomComparers/MultidimensionalArrayComparer~1.cs",
"chars": 3036,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing ObjectsComparer.Utils;\n\nnamespace ObjectsCompa"
},
{
"path": "ObjectsComparer/ObjectsComparer/CustomComparers/MultidimensionalArraysComparer.cs",
"chars": 1734,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Reflection;\nusing ObjectsComparer.Utils;\n\nnamespace Object"
},
{
"path": "ObjectsComparer/ObjectsComparer/CustomComparers/TypesComparer.cs",
"chars": 1495,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Reflection;\nusing ObjectsComparer.Utils;\n\nnamespace Object"
},
{
"path": "ObjectsComparer/ObjectsComparer/Difference.cs",
"chars": 2450,
"preview": "namespace ObjectsComparer\n{\n /// <summary>\n /// Represents difference in one member between objects.\n /// </su"
},
{
"path": "ObjectsComparer/ObjectsComparer/DifferenceTypes.cs",
"chars": 1187,
"preview": "using System.Collections;\n\nnamespace ObjectsComparer\n{\n /// <summary>\n /// Specifies types of the differences bet"
},
{
"path": "ObjectsComparer/ObjectsComparer/Exceptions/AmbiguousComparerOverrideResolutionException.cs",
"chars": 1644,
"preview": "using System;\nusing System.Reflection;\n\nnamespace ObjectsComparer.Exceptions\n{\n /// <summary>\n /// Represents err"
},
{
"path": "ObjectsComparer/ObjectsComparer/Exceptions/ValueComparerExistsException.cs",
"chars": 660,
"preview": "using System;\nusing System.Reflection;\n\nnamespace ObjectsComparer.Exceptions\n{\n /// <summary>\n /// Represents err"
},
{
"path": "ObjectsComparer/ObjectsComparer/IBaseComparer.cs",
"chars": 3871,
"preview": "using System;\nusing System.Linq.Expressions;\nusing System.Reflection;\n\nnamespace ObjectsComparer\n{\n /// <summary>\n "
},
{
"path": "ObjectsComparer/ObjectsComparer/IComparer.cs",
"chars": 2630,
"preview": "using System;\nusing System.Collections.Generic;\n\nnamespace ObjectsComparer\n{\n /// <summary>\n /// Defines methods t"
},
{
"path": "ObjectsComparer/ObjectsComparer/IComparersFactory.cs",
"chars": 1169,
"preview": "using System;\n\nnamespace ObjectsComparer\n{\n /// <summary>\n /// Defines methods to create type specific comparers.\n"
},
{
"path": "ObjectsComparer/ObjectsComparer/IComparer~1.cs",
"chars": 1259,
"preview": "using System.Collections.Generic;\n\nnamespace ObjectsComparer\n{\n /// <summary>\n /// Defines methods to compare comp"
},
{
"path": "ObjectsComparer/ObjectsComparer/LICENSE",
"chars": 1077,
"preview": "MIT License\n\nCopyright (c) 2019 Valerii Tereshchenko\n\nPermission is hereby granted, free of charge, to any person obtain"
},
{
"path": "ObjectsComparer/ObjectsComparer/ObjectsComparer.csproj",
"chars": 1310,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n <PropertyGroup>\n <TargetFrameworks>netstandard2.1;netstandard2.0;netstandard1.6"
},
{
"path": "ObjectsComparer/ObjectsComparer/ObjectsComparer.csproj.DotSettings",
"chars": 578,
"preview": "<wpf:ResourceDictionary xml:space=\"preserve\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:s=\"clr-namesp"
},
{
"path": "ObjectsComparer/ObjectsComparer/Properties/AssemblyInfo.cs",
"chars": 97,
"preview": "using System.Runtime.CompilerServices;\n\n[assembly: InternalsVisibleTo(\"ObjectsComparer.Tests\")]\n"
},
{
"path": "ObjectsComparer/ObjectsComparer/Utils/MemberInfoExtensions.cs",
"chars": 1553,
"preview": "using System;\nusing System.Linq.Expressions;\nusing System.Reflection;\n\nnamespace ObjectsComparer.Utils\n{\n internal s"
},
{
"path": "ObjectsComparer/ObjectsComparer/Utils/PropertyHelper.cs",
"chars": 1093,
"preview": "using System;\nusing System.Linq.Expressions;\nusing System.Reflection;\n\nnamespace ObjectsComparer.Utils\n{\n internal c"
},
{
"path": "ObjectsComparer/ObjectsComparer/Utils/TypeExtensions.cs",
"chars": 1464,
"preview": "using System;\nusing System.Linq;\nusing System.Reflection;\n\nnamespace ObjectsComparer.Utils\n{\n internal static class "
},
{
"path": "ObjectsComparer/ObjectsComparer/ValueComparers/AbstractValueComparer.cs",
"chars": 485,
"preview": "namespace ObjectsComparer\n{\n /// <summary>\n /// Implementation of <see cref=\"IValueComparer\"/> which provides sim"
},
{
"path": "ObjectsComparer/ObjectsComparer/ValueComparers/AbstractValueComparer~1.cs",
"chars": 1929,
"preview": "namespace ObjectsComparer\n{\n /// <summary>\n /// Implementation of <see cref=\"IValueComparer{T}\"/> which provides "
},
{
"path": "ObjectsComparer/ObjectsComparer/ValueComparers/DefaultValueComparer.cs",
"chars": 1940,
"preview": "namespace ObjectsComparer\n{\n /// <summary>\n /// Default implementation of <see cref=\"IValueComparer\"/>\n /// </"
},
{
"path": "ObjectsComparer/ObjectsComparer/ValueComparers/DefaultValueValueComparer.cs",
"chars": 2298,
"preview": "namespace ObjectsComparer\n{\n /// <summary>\n /// Allows to consider provided value and default value of type <see "
},
{
"path": "ObjectsComparer/ObjectsComparer/ValueComparers/DoNotCompareValueComparer.cs",
"chars": 1864,
"preview": "namespace ObjectsComparer\n{\n /// <summary>\n /// Allows to ignore comparison. Considers all values as equal.\n /"
},
{
"path": "ObjectsComparer/ObjectsComparer/ValueComparers/DynamicValueComparer.cs",
"chars": 3108,
"preview": "using System;\nusing System.Reflection;\n\nnamespace ObjectsComparer\n{\n /// <summary>\n /// Allows to provide compari"
},
{
"path": "ObjectsComparer/ObjectsComparer/ValueComparers/IValueComparer.cs",
"chars": 962,
"preview": "namespace ObjectsComparer\n{\n /// <summary>\n /// Defines a generalized comparison method to compare 2 objects.\n "
},
{
"path": "ObjectsComparer/ObjectsComparer/ValueComparers/IValueComparer~1.cs",
"chars": 1043,
"preview": "namespace ObjectsComparer\n{\n /// <summary>\n /// Defines a generalized type-specific comparison method to compare "
},
{
"path": "ObjectsComparer/ObjectsComparer/ValueComparers/IgnoreCaseStringsValueComparer.cs",
"chars": 1565,
"preview": "using System;\n\nnamespace ObjectsComparer\n{\n /// <summary>\n /// Allows to compare string ignoring case.\n /// </"
},
{
"path": "ObjectsComparer/ObjectsComparer/ValueComparers/NulableStringsValueComparer.cs",
"chars": 1836,
"preview": "namespace ObjectsComparer\n{\n /// <summary>\n /// Allows to compare strings considering that null and empty string "
},
{
"path": "ObjectsComparer/ObjectsComparer/ValueComparers/ToStringComparer.cs",
"chars": 244,
"preview": "namespace ObjectsComparer\n{\n public class ToStringComparer<T> : DynamicValueComparer<T>\n {\n public ToStrin"
},
{
"path": "ObjectsComparer/ObjectsComparer/ValueComparers/UriComparer.cs",
"chars": 972,
"preview": "using System;\n\nnamespace ObjectsComparer\n{\n public class UriComparer: DynamicValueComparer<Uri>\n {\n privat"
},
{
"path": "ObjectsComparer/ObjectsComparer.Examples/BasicExamples/BasicExampleTests.cs",
"chars": 17946,
"preview": "using System.Collections;\nusing System.Collections.Generic;\nusing System.Dynamic;\nusing System.Globalization;\nusing Sys"
},
{
"path": "ObjectsComparer/ObjectsComparer.Examples/BasicExamples/ClassA.cs",
"chars": 323,
"preview": "namespace ObjectsComparer.Examples.BasicExamples\n{\n public class ClassA\n {\n public string StringProperty {"
},
{
"path": "ObjectsComparer/ObjectsComparer.Examples/Example1/Error.cs",
"chars": 165,
"preview": "namespace ObjectsComparer.Examples.Example1\n{\n public class Error\n {\n public int Id { get; set; }\n\n "
},
{
"path": "ObjectsComparer/ObjectsComparer.Examples/Example1/Example1Tests.cs",
"chars": 4243,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing NUnit.Framework;\nusing static ObjectsComparer."
},
{
"path": "ObjectsComparer/ObjectsComparer.Examples/Example1/Message.cs",
"chars": 592,
"preview": "using System;\nusing System.Collections.Generic;\n\nnamespace ObjectsComparer.Examples.Example1\n{\n public class Message"
},
{
"path": "ObjectsComparer/ObjectsComparer.Examples/Example2/Example2Tests.cs",
"chars": 2468,
"preview": "using System;\nusing System.Linq;\nusing NUnit.Framework;\nusing static ObjectsComparer.Examples.OutputHelper;\n\n// ReSharp"
},
{
"path": "ObjectsComparer/ObjectsComparer.Examples/Example2/MyComparersFactory.cs",
"chars": 1124,
"preview": "using System;\n\nnamespace ObjectsComparer.Examples.Example2\n{\n public class MyComparersFactory : ComparersFactory\n "
},
{
"path": "ObjectsComparer/ObjectsComparer.Examples/Example2/Person.cs",
"chars": 471,
"preview": "using System;\n\nnamespace ObjectsComparer.Examples.Example2\n{\n public class Person\n {\n public Guid PersonId"
},
{
"path": "ObjectsComparer/ObjectsComparer.Examples/Example2/PhoneNumberComparer.cs",
"chars": 573,
"preview": "using System.Linq;\n\nnamespace ObjectsComparer.Examples.Example2\n{\n public class PhoneNumberComparer: AbstractValueCo"
},
{
"path": "ObjectsComparer/ObjectsComparer.Examples/Example3/Example3Tests.cs",
"chars": 5119,
"preview": "using System;\nusing System.Dynamic;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection;\nusing System.Text;\nusi"
},
{
"path": "ObjectsComparer/ObjectsComparer.Examples/Example3/Settings0.json",
"chars": 1050,
"preview": "{\n \"ConnectionString\": \"USER ID=superuser;PASSWORD=superpassword;DATA SOURCE=localhost:1111\",\n \"Email\": {\n \"Port\": "
},
{
"path": "ObjectsComparer/ObjectsComparer.Examples/Example3/Settings1.json",
"chars": 867,
"preview": "{\n \"ConnectionString\": \"USER ID=admin;PASSWORD=*****;DATA SOURCE=localhost:22222\",\n \"Email\": {\n \"Port\": 25,\n \"Ho"
},
{
"path": "ObjectsComparer/ObjectsComparer.Examples/Example3/Settings2.json",
"chars": 874,
"preview": "{\n \"ConnectionString\": \"USER ID=superuser;PASSWORD=superpassword;DATA SOURCE=localhost:1111\",\n \"Email\": {\n \"Port\": "
},
{
"path": "ObjectsComparer/ObjectsComparer.Examples/Example4/CustomFormulaItemsComparer.cs",
"chars": 1649,
"preview": "using System.Collections.Generic;\nusing System.Linq;\n\nnamespace ObjectsComparer.Examples.Example4\n{\n public class Cu"
},
{
"path": "ObjectsComparer/ObjectsComparer.Examples/Example4/Example4Tests.cs",
"chars": 4232,
"preview": "using System.Collections.Generic;\nusing System.Linq;\nusing NUnit.Framework;\nusing static ObjectsComparer.Examples.Outpu"
},
{
"path": "ObjectsComparer/ObjectsComparer.Examples/Example4/Formula.cs",
"chars": 253,
"preview": "using System.Collections.Generic;\n\nnamespace ObjectsComparer.Examples.Example4\n{\n public class Formula\n {\n "
},
{
"path": "ObjectsComparer/ObjectsComparer.Examples/Example4/FormulaItem.cs",
"chars": 255,
"preview": "namespace ObjectsComparer.Examples.Example4\n{\n public class FormulaItem\n {\n public long Id { get; set; }\n "
},
{
"path": "ObjectsComparer/ObjectsComparer.Examples/Example4/MyComparersFactory.cs",
"chars": 625,
"preview": "using System.Collections.Generic;\n\nnamespace ObjectsComparer.Examples.Example4\n{\n public class MyComparersFactory : "
},
{
"path": "ObjectsComparer/ObjectsComparer.Examples/Example5/Error.cs",
"chars": 244,
"preview": "namespace ObjectsComparer.Examples.Example5\n{\n public class Error\n {\n [Ignore]\n public int Id { get"
},
{
"path": "ObjectsComparer/ObjectsComparer.Examples/Example5/Example5Tests.cs",
"chars": 815,
"preview": "using NUnit.Framework;\n\nnamespace ObjectsComparer.Examples.Example5\n{\n [TestFixture]\n public class Example5Tests\n"
},
{
"path": "ObjectsComparer/ObjectsComparer.Examples/Example5/IgnoreAttribute.cs",
"chars": 168,
"preview": "using System;\n\nnamespace ObjectsComparer.Examples.Example5\n{\n [AttributeUsage(AttributeTargets.Property)]\n public"
},
{
"path": "ObjectsComparer/ObjectsComparer.Examples/ObjectsComparer.Examples.csproj",
"chars": 1240,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n <PropertyGroup>\n <TargetFrameworks>netcoreapp2.0;net45</TargetFrameworks>\n </P"
},
{
"path": "ObjectsComparer/ObjectsComparer.Examples/OutputHelper.cs",
"chars": 386,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\n\n\nnamespace ObjectsComparer.Examples\n{\n pu"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/AbstractComparerGenericTests.cs",
"chars": 2574,
"preview": "using System.Collections.Generic;\nusing NSubstitute;\nusing NUnit.Framework;\n\nnamespace ObjectsComparer.Tests\n{\n [Tes"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/AbstractComparerTests.cs",
"chars": 5041,
"preview": "using System.Collections.Generic;\nusing NSubstitute;\nusing NUnit.Framework;\n\nnamespace ObjectsComparer.Tests\n{\n [Tes"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/ComparerNonGenericTests.cs",
"chars": 1700,
"preview": "using System;\nusing System.Linq;\nusing NUnit.Framework;\nusing ObjectsComparer.Tests.TestClasses;\n\nnamespace ObjectsComp"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/ComparerOverridesCollectionTests.cs",
"chars": 15710,
"preview": "using System;\nusing System.Reflection;\nusing NSubstitute;\nusing NUnit.Framework;\nusing ObjectsComparer.Exceptions;\n\nnam"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/ComparerTests.cs",
"chars": 16803,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing NSubstitute;\nusing NUnit.Framework;\nusing Obje"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/Comparer_CompilerGeneratedObjectsTests.cs",
"chars": 11510,
"preview": "using System.Linq;\nusing NUnit.Framework;\nusing NSubstitute;\n\nnamespace ObjectsComparer.Tests\n{\n [TestFixture]\n p"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/Comparer_DynamicObjectsTests.cs",
"chars": 12977,
"preview": "using System.Linq;\nusing NUnit.Framework;\nusing System.Collections.Generic;\nusing System.Dynamic;\nusing NSubstitute;\n\nn"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/Comparer_ExpandoObjectsTests.cs",
"chars": 12160,
"preview": "using System.Linq;\nusing NUnit.Framework;\nusing System.Collections.Generic;\nusing System.Dynamic;\nusing Newtonsoft.Json"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/Comparer_GenericEnumerableTests.cs",
"chars": 28007,
"preview": "using System.Collections.ObjectModel;\nusing System.Linq;\nusing NUnit.Framework;\nusing ObjectsComparer.Tests.TestClasses"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/Comparer_IPEndPointTests.cs",
"chars": 1198,
"preview": "using System.Linq;\nusing System.Net;\nusing NUnit.Framework;\n\nnamespace ObjectsComparer.Tests\n{\n [TestFixture]\n pu"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/Comparer_Issue24Tests.cs",
"chars": 1785,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing NSubstitute;\nusing NUnit.Framework;\nusing Obje"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/Comparer_MultidimensionalArraysTests.cs",
"chars": 14807,
"preview": "using System.Linq;\nusing NUnit.Framework;\nusing ObjectsComparer.Tests.TestClasses;\n\nnamespace ObjectsComparer.Tests\n{\n "
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/Comparer_NonGenericEnumerableTests.cs",
"chars": 6680,
"preview": "using System.Collections;\nusing System.Linq;\nusing NUnit.Framework;\nusing ObjectsComparer.Tests.TestClasses;\n\nnamespace"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/Comparer_OverridesTests.cs",
"chars": 18448,
"preview": "using System.Linq;\nusing System.Reflection;\nusing NSubstitute;\nusing NUnit.Framework;\nusing ObjectsComparer.Tests.TestC"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/Comparer_StringBuilderTests.cs",
"chars": 1221,
"preview": "using System.Linq;\nusing NUnit.Framework;\nusing System.Text;\n\nnamespace ObjectsComparer.Tests\n{\n [TestFixture]\n p"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/Comparer_UriTests.cs",
"chars": 1792,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing NUnit.Framework;\n\nnamespace ObjectsComparer.Te"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/ComparersFactoryTests.cs",
"chars": 2435,
"preview": "using System.Collections.Generic;\nusing NSubstitute;\nusing NUnit.Framework;\nusing ObjectsComparer.Tests.TestClasses;\n\nn"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/ComparisonSettingsTests.cs",
"chars": 1553,
"preview": "using System.Collections.Generic;\nusing NUnit.Framework;\n\nnamespace ObjectsComparer.Tests\n{\n [TestFixture]\n publi"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/CustomComparers/AbstractValueComparerTests.cs",
"chars": 419,
"preview": "using NSubstitute;\nusing NUnit.Framework;\n\nnamespace ObjectsComparer.Tests\n{\n [TestFixture]\n public class Abstrac"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/CustomComparers/DynamicValueComparerTests.cs",
"chars": 4230,
"preview": "using System;\nusing NUnit.Framework;\n\nnamespace ObjectsComparer.Tests\n{\n [TestFixture]\n public class DynamicValue"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/CustomComparers/EnumerablesComparerGenericTests.cs",
"chars": 1318,
"preview": "using NUnit.Framework;\nusing System;\nusing System.Collections.Generic;\nusing ObjectsComparer.Tests.TestClasses;\n\nnamesp"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/CustomComparers/EnumerablesComparerTests.cs",
"chars": 1277,
"preview": "using NUnit.Framework;\nusing System;\nusing System.Collections.Generic;\nusing ObjectsComparer.Tests.TestClasses;\n\nnamesp"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/CustomComparers/HashSetsComparerTests.cs",
"chars": 1303,
"preview": "using NUnit.Framework;\nusing System;\nusing System.Collections.Generic;\nusing ObjectsComparer.Tests.TestClasses;\n\nnamesp"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/CustomComparers/TypesComparerTests.cs",
"chars": 1655,
"preview": "using NUnit.Framework;\nusing System;\n\nnamespace ObjectsComparer.Tests\n{\n [TestFixture]\n public class TypesCompare"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/DifferenceTests.cs",
"chars": 496,
"preview": "using NUnit.Framework;\n\nnamespace ObjectsComparer.Tests\n{\n [TestFixture]\n public class DifferenceTests\n {\n "
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/ObjectsComparer.Tests.csproj",
"chars": 694,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n <PropertyGroup>\n <TargetFrameworks>netcoreapp3.0;netcoreapp2.0;net45</TargetFram"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/ObjectsComparer.Tests.csproj.DotSettings",
"chars": 578,
"preview": "<wpf:ResourceDictionary xml:space=\"preserve\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:s=\"clr-namesp"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/ParentInterfacePropertiesTests.cs",
"chars": 1335,
"preview": "using System.Collections.Generic;\nusing System.Linq;\nusing NUnit.Framework;\n\nnamespace ObjectsComparer.Tests\n{\n [Tes"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/TestClasses/A.cs",
"chars": 2199,
"preview": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing S"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/TestClasses/B.cs",
"chars": 126,
"preview": "namespace ObjectsComparer.Tests.TestClasses\n{\n public class B\n {\n public string Property1 { get; set; }\n "
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/TestClasses/Child.cs",
"chars": 457,
"preview": "namespace ObjectsComparer.Tests.TestClasses\n{\n using ObjectsComparer.Attributes;\n\n public class Child\n {\n #region"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/TestClasses/CollectionOfB.cs",
"chars": 1123,
"preview": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing S"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/TestClasses/EnumerableImplementation.cs",
"chars": 477,
"preview": "using System.Collections;\n\nnamespace ObjectsComparer.Tests.TestClasses\n{\n internal class EnumerableImplementation: I"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/TestClasses/FlagsEnum.cs",
"chars": 189,
"preview": "using System;\n\nnamespace ObjectsComparer.Tests.TestClasses\n{\n [Flags]\n public enum FlagsEnum\n {\n Flag1 "
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/TestClasses/ITestInterface.cs",
"chars": 137,
"preview": "namespace ObjectsComparer.Tests.TestClasses\n{\n internal interface ITestInterface\n {\n string Property { get"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/TestClasses/InheritedFromB.cs",
"chars": 146,
"preview": "namespace ObjectsComparer.Tests.TestClasses\n{\n internal class InheritedFromB: B\n {\n public string NewPrope"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/TestClasses/MultidimensionalArrays.cs",
"chars": 242,
"preview": "namespace ObjectsComparer.Tests.TestClasses\n{\n public class MultidimensionalArrays\n {\n public int[,] IntIn"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/TestClasses/Parent.cs",
"chars": 286,
"preview": "namespace ObjectsComparer.Tests.TestClasses\n{\n using System.Collections.ObjectModel;\n\n public class Parent\n {\n "
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/TestClasses/ParentChild.cs",
"chars": 896,
"preview": "namespace ObjectsComparer.Tests.TestClasses\n{\n using System.Collections.ObjectModel;\n\n using NUnit.Framework;\n\n usin"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/TestClasses/TestEnum.cs",
"chars": 119,
"preview": "namespace ObjectsComparer.Tests.TestClasses\n{\n internal enum TestEnum\n {\n Value1,\n Value2\n }\n}\n"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/TestClasses/TestInterfaceImplementation1.cs",
"chars": 170,
"preview": "namespace ObjectsComparer.Tests.TestClasses\n{\n internal class TestInterfaceImplementation1: ITestInterface\n {\n "
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/TestClasses/TestInterfaceImplementation2.cs",
"chars": 220,
"preview": "namespace ObjectsComparer.Tests.TestClasses\n{\n internal class TestInterfaceImplementation2: ITestInterface\n {\n "
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/TestClasses/TestStruct.cs",
"chars": 153,
"preview": "namespace ObjectsComparer.Tests.TestClasses\n{\n internal struct TestStruct\n {\n public string FieldA;\n\n "
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/Utils/TypeExtensionsTests.cs",
"chars": 1609,
"preview": "using System;\nusing System.Collections.Generic;\nusing NUnit.Framework;\nusing ObjectsComparer.Utils;\n\nnamespace ObjectsC"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/ValueComparers/DefaultValueComparerTests.cs",
"chars": 1125,
"preview": "using NUnit.Framework;\n\nnamespace ObjectsComparer.Tests\n{\n [TestFixture]\n public class DefaultValueComparerTests\n"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/ValueComparers/DefaultValueValueComparerTests.cs",
"chars": 1690,
"preview": "using NUnit.Framework;\n\nnamespace ObjectsComparer.Tests\n{\n [TestFixture]\n public class DefaultValueValueComparerT"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/ValueComparers/DoNotCompareValueComparerTests.cs",
"chars": 776,
"preview": "using NUnit.Framework;\n\nnamespace ObjectsComparer.Tests\n{\n [TestFixture]\n public class DoNotCompareValueComparerT"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/ValueComparers/IgnoreCaseStringsValueComparerTests.cs",
"chars": 769,
"preview": "using NUnit.Framework;\n\nnamespace ObjectsComparer.Tests\n{\n [TestFixture]\n public class IgnoreCaseStringsValueComp"
},
{
"path": "ObjectsComparer/ObjectsComparer.Tests/ValueComparers/NulableStringsValueComparerTests.cs",
"chars": 1056,
"preview": "using NUnit.Framework;\n\nnamespace ObjectsComparer.Tests\n{\n [TestFixture]\n public class NulableStringsValueCompare"
},
{
"path": "ObjectsComparer/ObjectsComparer.sln",
"chars": 2148,
"preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 15\nVisualStudioVersion = 15.0.27428.2011\nM"
},
{
"path": "README.md",
"chars": 35028,
"preview": "\n\n# Objects Comparer\n## Intro"
}
]
About this extraction
This page contains the full source code of the ValeraT1982/ObjectsComparer GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 126 files (369.9 KB), approximately 87.1k tokens, and a symbol index with 645 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.